MVVM架構~Knockoutjs系列之對象與(yu)對象組合
在(zai)面向對(dui)(dui)(dui)象(xiang)(xiang)的程序設(she)計里(li),對(dui)(dui)(dui)象(xiang)(xiang)是核心,一切皆(jie)為對(dui)(dui)(dui)象(xiang)(xiang),對(dui)(dui)(dui)象(xiang)(xiang)與對(dui)(dui)(dui)象(xiang)(xiang)之間的關系可(ke)以表(biao)現為繼承和(he)組合,而在(zai)Knockoutjs或者JS里(li),也存在(zai)著對(dui)(dui)(dui)象(xiang)(xiang)的概(gai)念,今天主要說一下JS里(li)的對(dui)(dui)(dui)象(xiang)(xiang)及對(dui)(dui)(dui)象(xiang)(xiang)的組合。
JS里對(dui)象(xiang)可以使(shi)(shi)用(yong)(yong){}生成,也可以使(shi)(shi)用(yong)(yong)function(){}方式生成,而使(shi)(shi)用(yong)(yong)function(){}方式我認為更(geng)靈(ling)活,使(shi)(shi)用(yong)(yong){}方式更(geng)正規,我這里總(zong)結了一(yi)下,也是我的習慣,如(ru)果對(dui)象(xiang)只是getter,setter的屬性塊,
可(ke)以使(shi)用{}的方式(shi),如果對象比較(jiao)復雜(za),由屬性,方法(fa) 組成,這時最好使(shi)用function(){}的方式(shi),下面舉例(li)說(shuo)明。
下面定義一個(ge)user對象,使用{}方式
var User={ Name:"zzl", Gander:"male" }
下(xia)面是一個User對象的(de)function(){}的(de)形式
var User=function(){ this.Name="zzl"; this.Gander="male"; } //為了調用上的方(fang)便,層次的清晰(xi),我(wo)們在調用根元素時,最好把this重新定義,看下面代(dai)碼: var User=function(){ var self=this;//這里的self表示User對像(xiang) self.Name="zzl"; self.Gander="male"; self.Remove=function(){ console.log(this.Name);//這(zhe)里的this表示(shi)當前你(ni)觸發的記錄(user可以有多個) } }
好了,有了對(dui)象的(de)(de)(de)概念(nian)之后,我們(men)(men)來看一下Knockoutjs里如何使(shi)用對(dui)象,事(shi)實上,在Knockoutjs里的(de)(de)(de)viewmodel,即我們(men)(men)的(de)(de)(de)頁面數據(ju)綁(bang)定(ding)(ding)源,就是一個對(dui)象,它(ta)也完全支持{}和function(){}兩種方式,而我習慣上使(shi)用第二(er)次,呵呵,下面我們(men)(men)為view返回(hui)一個userList的(de)(de)(de)viewmodel,用來輸出一個user對(dui)象的(de)(de)(de)集(ji)合(he),將它(ta)綁(bang)定(ding)(ding)到<table>元(yuan)素上。
JS部分代碼:
var User = function (id, name) { self = this; self.id = ko.observable(id); self.name = ko.observable(name); self.editing = ko.observable(false); self.edit = function () {//這里的(de)this是當前調用的(de)對(dui)象,而(er)不是UserList,而(er)self才是UserList對(dui)象,這也是為(wei)什么要使用var self = this語(yu)句(ju)的(de)原因 this.editing(true); } }; //集合屬性和方法 var UserList = function () { var self = this; self.users = ko.observableArray(); for (var i = 0; i < 10; i++) { self.users.push(new User(i, "zzl")); } // Behavior Remove self.removePerson = function () {//data-bind="click:$parent.removePerson"//這句為調(diao)用當前對(dui)象(xiang)的父對(dui)象(xiang)上的方(fang)法 self.users.remove(this); } } ko.applyBindings(new UserList());//像view返回(hui)一個User集合
看一下(xia)HTML代碼:
<div class="liveExample"> <table> <thead> <tr> <th>編號</th> <th>姓名</th> <th></th> </tr> </thead> <tbody data-bind="template:{name:'list',foreach: users}"> </tbody> </table> </div> <script type="text/html" id="list"> <tr> <td data-bind="text:id"></td> <td> <input type="text" data-bind="value:name, click:edit" /></td> <td> <a href="#" data-bind="click:$parent.removePerson">移除</a> <span data-bind="visible:editing"><a data-bind='click:save'>保存</a></span> </td> </tr> </script>
上面的(de)實例中(zhong),實現了對象(xiang)集合的(de)移除操作,即從users里(li)移除一個(ge)User對象(xiang),而保(bao)存按鈕的(de)顯示是通過你(ni)是否單(dan)擊文本框決定的(de),而代(dai)碼(ma)中(zhong)的(de)$parent.removePerson意思是說,調用users對象(xiang)的(de)上一級對象(xiang)的(de)removePerson方法,如(ru)果在(zai)C#里(li),這個(ge)結構
會是這樣實現(xian),看(kan)代(dai)碼:
classUser
{ public int Id{get;set;} public string Name{get;set;} } class UserList
{ public User[] Users{get;set;} public void RemovePerson(User entity)
{ this.Users.Remove(entity); } }
怎么(me)樣(yang),看(kan)了我的C#代碼分析(xi),學起JS來也不那么(me)費力了吧,呵呵。