1. 程式人生 > >利用avalon 實現一個簡單的成績單

利用avalon 實現一個簡單的成績單

本文的靈感是來自Halower的這篇博文,他是使用knockout與jQuery實現的。不過我覺得MVVM本來就強大的事件繫結功能,因此用jQuery 是多此一舉。另,他也用了一些面向物件的寫法。我個人認為,純資料就該好好當純資料,作為資料模型(M)而存在,想操作資料,則交由檢視模型(VM)。在angularjs流行的一些成規,都是要求大家不要自己操作DOM,DOM是框架自行幫你偷偷搞定。這也與avalon一直提倡的“操作資料即操作DOM”的理念相符。由於avalon巧妙地利用了Object.defineProperty, __defineSetter__, __defineGetter__, VBScript等方法把等於號(=)過載了,因此與檢視的同步就變得比其他MVVM更隱祕神奇。那麼接著下來,讓我們看看avalon是如何實現這個功能吧。

首先是檢視層,裡面的繫結屬性其實可以在VM中的屬性定了下來再新增。這也涉及MVVM另一個優勢,分離關注點,因此切圖與JS程式設計可以同時進行。由於JS程式碼不進行DOM操作,頁面長得怎麼樣也無所謂,我又不需要選擇器引擎!

        <div ms-controller="grid" class="grid" >
            <div>
                <p> <input ms-duplex="id">
                    <input ms-duplex="name">
                    <input ms-duplex="score" data-duplex-event="change"></p>
                <p><button ms-click="add"> add</button></p>
            </div>
            <p>共{{array.size()}}條------------------合計{{total}}分</p>
            <table>
                <thead>
                    <tr>
                        <th>ID</th> <th>姓名</th> <th>分數</th> <th>操作</th>
                    </tr>
                </thead>
              
                <tbody ms-each-el="array">
                    <tr>
                        <td>{{el.id}}</td>
                        <td>{{el.name}}</td>
                        <td>{{el.score}}</td>
                        <td align="center"><a ms-click="$remove" href="javascript:void(0)">移除</a></td>
                    </tr>
                </tbody>
            </table>
            <textarea ms-value="JSON.stringify(array.$model)" style="width:90%;height:220px;"></textarea>
        </div>

樣式隨便弄弄:

            .grid table{
                border:1px solid #000;
                width:500px;
                border-collapse: collapse;
            }
            .grid button{
                width:400px;
                background: orange;
            }
            .grid table th, .grid table td{
                border:1px solid #000;
                padding: 2px 5px;
            }

從HTML結構來看,分為兩部分,一個是用於輸入資料,另一個是呈現所有資料,資料上方還有個小統計。輸入資料部分有三個輸入項,我們對分數中進行校驗,只保證其是數字就行了,目的是為了相加,因為input的value屬性總為一個字串型別。下方有個按鈕,用於提交。呈現區為一個table,所有MVVM框架都支援陣列迴圈輸出,我的與angular走得很近。在迴圈區域,裡面還內建一個$remove方法,用於刪除監控陣列中的某一個元素,這個比knockout人性化多了。下面是JS部分,你是看不到一句操作DOM的程式碼。

//如果大家對avalon不熟悉,可以參看這篇入門教程 http://www.cnblogs.com/rubylouvre/p/3181291.html
            avalon.ready(function() {
                var model = avalon.define('grid', function(vm) {
                    vm.id = "" 
                    vm.name = ""
                    vm.score = 0
                    vm.total = 0

                    vm.add = function() {
                       if(vm.id && vm.name ){
                           vm.array.push({
                              id: vm.id,
                              name: vm.name,
                              score: vm.score
                           })
                       }
                    }
                    vm.array = []           
               });

                model.$watch("score", function(a) {
                        var a = Number(a) || 0
                        a = a > 100 ?  100 : a < 0 ? 0 : a//強制轉換為0~100間
                        model.score = a
                })
                model.array.$watch("length", function() {
                    var a = 0
                    model.array.forEach(function(el) {
                        a += el.score//求得總數
                    })
                    model.total = a;
                    model.id = ""
                    model.name = ""
                    model.score = 0
                })
                model.array = [
                    {id: "d1", name: "李世民", score: 67},
                    {id: "d2", name: "贏政", score: 90}
                ]

                avalon.scan();
            });

我們在define方法中定義了VM所有用到的資料,什麼id, name, score, array, 還有需要綁到檢視中的add方法。資料校驗或資料變動時需要做的操作,我們是用$watch實現,它們被安排到define方法外,這是一個好主意。然後,就沒有然後了!這就是MVVM的神奇之處,因為我們在檢視中使用了{{}}, ms-click已經指明瞭它們的行為。因此當資料變動時,框架自然明白自己該什麼做。

共{{array.size()}}條------------------合計{{total}}分

ID 姓名 分數 操作
{{el.id}} {{el.name}} {{el.score}} 移除

目前我與5群的一些人已經將avalon應用於公司的生產環境,反應還是不錯。雖然目前還不時冒出一些怪異的BUG,但難度不至於影響我們的進度,基本上半天就能修,比如說IE9-10的option標籤的value問題,firefox 全系列下,未插入DOM樹的元素的display樣式取值問題,這是jQuery也沒報到的新東西。有的話,我在做mass Framework時已經遇到過了。MVVM是一個全新的領域,要求對使用者全面隱藏DOM操作,並將整個DOM樹作為一個動態模板或數個複用的子模板,另外,DOM樹其實也被我框架看作為一個Ioc容器的配置檔案。如此種種,遭遇新的問題在所難免,但只要方向是對的,這就是康莊大道。雖然它與jQuery走的是一條截然不同的路,但明顯優於jQuery。jQuery與DOM存在強依賴,導致維護成本奇高。這正是西方繼jQuery後,又孜孜不倦發明backbone, canjs, knockout, emberjs, angular的原因。現在國內的技術步伐普通比外國慢兩三年,現在前端MVVM已經在外國非常盛行,希望國人不要再落後太多了。

相關推薦

利用avalon 實現一個簡單成績單

本文的靈感是來自Halower的這篇博文,他是使用knockout與jQuery實現的。不過我覺得MVVM本來就強大的事件繫結功能,因此用jQuery 是多此一舉。另,他也用了一些面向物件的寫法。我個人認為,純資料就該好好當純資料,作為資料模型(M)而存在,想操作資料,則交由檢視模型(VM)。在angular

利用AOP實現一個簡單的快取儲存、清除的工具

基本要求:利用aop實現一個簡單的快取儲存、清除的工具,從實際使用上來說,切面應該在provider層。在service層方法呼叫和資料庫查詢之間生效。為了簡化過程,不要求與資料庫互動,資料可以隨機生成,不要求使用redis等中介軟體,可以直接快取到記憶體中。 程式碼實現非常的基礎,能夠很好

.NET Core微服務之路:利用DotNetty實現一個簡單的通訊過程

  上一篇我們已經全面的介紹過《基於gRPC服務發現與服務治理的方案》,我們先複習一下RPC的呼叫過程(筆者會在這一節的幾篇文章中反覆的強調這個過程呼叫方案),看下圖

利用java實現一個簡單的連結串列結構

定義: 所謂連結串列就是指在某節點儲存資料的過程中還要有一個屬性用來指向下一個連結串列節點,這樣的資料儲存方式叫做連結串列 連結串列優缺點: 優點:易於儲存和刪除 缺點:查詢起來較麻煩 下面我們用java來實現如下連結串列結構: 首先定義節點類: 複製程式碼package LinkTest;/*

利用java實現一個簡單的鏈表結構

oot null pri lin 遞歸遍歷 tom args oid per 定義: 所謂鏈表就是指在某節點存儲數據的過程中還要有一個屬性用來指向下一個鏈表節點,這樣的數據存儲方式叫做鏈表 鏈表優缺點: 優點:易於存儲和刪除 缺點:查詢起來較麻煩 下面我們用java來實現如

【IOS】利用ASIHTTPRequest 實現一個簡單的登陸驗證

【原創作品, 歡迎轉載,轉載請在明顯處註明! 謝謝。 今天給大家帶來一個簡單的登陸驗證,用的是ASIHttpRequest 這個開源類庫,使用的方法很簡單,從網上下載下來以後,新增到專案中,並新增一下這些框架。 下面上程式碼 // // ViewControll

利用scrapy框架實現一個簡單的爬蟲專案

首先簡單介紹一下什麼是scrapy框架?具體詳情見百科!!! 總之,scrapy是一個用於python開發抓取網站網頁的框架,更加通俗的講就是爬蟲框架!!! 下面就是利用scrapy爬取web的一個小專案: import scrapy class BooksSpi

【原創】實現一個簡單的移動端左右滑動翻頁+ 點選下標翻頁 利用:HTML5+CSS+Js

//【如何做一個簡單的手機端頁面的翻頁】//第一步:建立移動端頁面內  HTML + CSS  【注】可用彈性佈局   但需要注意的是  外層盒子的定位//第二步: 思考問題  要實現怎樣的效果?//1. 手指滑動時觸發事件【左右】兩個方向  //2.點選footer部分的下

【Android遊戲開發十六】Android Gesture之【觸控式螢幕手勢識別】操作!利用觸控式螢幕手勢實現一個簡單切換圖片的功能!

原創,轉載務必在明顯處註明:很多童鞋說我的程式碼執行後,點選home或者back後會程式異常,如果你也這樣遇到過,那麼你肯定沒有仔細讀完Himi的博文,第十九篇Himi專門寫了關於這些錯誤的原因和解決方法,這裡我在部落格都補充說明下,省的童鞋們總疑惑這一塊;請點選下面聯絡進入

利用http協議實現一個簡單的web伺服器

目錄檔案: htdoc: html檔案: <html> <head> <h1>hello</h1> </head> <body> <p

【遠端呼叫框架】如何實現一個簡單的RPC框架(三)優化一:利用動態代理改變使用者服務呼叫方式

【如何實現一個簡單的RPC框架】系列文章: 這篇部落格,在(一)(二)的基礎上,對第一版本實現的服務框架進行改善,不定期更新,每次更新都會增加一個優化的地方。 1、優化一:利用動態代理改變使用者服務呼叫方式 1.1 目的 改變使用者

實現一個簡單的lazyman

實現 blog cti name init timeout bin bsp stack function lazyman(name) { return new lazyman.fn.init(name); } lazyman.fn = lazyman.proto

用java實現一個簡單的單用戶登陸功能的思路

get 單用戶 這樣的 簡單的 lock ref 數據庫 清除 一個 引用 所謂“單用戶單賬戶登錄”是指:在同一系統中,一個用戶名不能在兩個地方同時登錄。 我們參照 QQ 實現效果:當某賬號在 A 處登錄後,在未退出的情況下,如果再到 B 處登錄,那麽,系統會擠下 A 處

【Java】Swing+IO流實現一個簡單的文件加密程序

als oncommand override fault 源文件 abs directory imp select EncrytService package com.my.service; import java.io.File; import java

【Java】Swing+IO流實現一個簡單的文件加密程序(較完整版)

move 初始 baidu images 文件選擇器 while login 一個 ktr 留著參考 beans package com.my.bean; import java.io.Serializable; public class

Linux中實現一個簡單的進度條【轉】

做的 會有 發現 文件 rsquo 實時 時間 改進 常見 轉自:http://blog.csdn.net/yuehailin/article/details/53999288 說起進度條,其實大家常常見到,比如說你在下載視頻或文件的時候,提示你當前下載進度的就是我們今天

用 C# 實現一個簡單的 Rest Service 供外部調用

message [] operation rem adk www span method title 用 C# 實現一個簡單的 Restful Service 供外部調用,大體總結為4點: The service contract (the methods it o

jQuery實現一個簡單的購物車功能

名稱 展示 -1 set margin for button ans return 最近由於工作需要的原因,開始系統學習jQuery的知識,然後跟著一個視頻教程做了一個購物車的功能,現總結如下。 第一步:準備HTML頁面,代碼如下: <!DOCTYPE html P

實現一個簡單的ConnectionPool

方法 == span sql 需要 動手 cti 修改 使用 看了一圈, 沒看到稍微好用的ConnectionPool, 除了一個aiomysql, 但是這個是異步的, 我暫時沒有用到這麽高版本的Python, 所以就動手造一個輪子. 原理比較簡單, 先造一個線程安全的集

實現一個簡單的虛擬demo算法

child mov 箭頭 內存 架構模式 ren 操作 inpu 設置 假如現在你需要寫一個像下面一樣的表格的應用程序,這個表格可以根據不同的字段進行升序或者降序的展示。 這個應用程序看起來很簡單,你可以想出好幾種不同的方式來寫。最容易想到的可能是,在你的 JavaScr