寫knockout的人都知道,想聲明一個綁定對象須要這麼寫。javascript
function User(model) { this.Id = ko.observable(model ? model.Id : "---"); this.Name = ko.observable(model ? model.Name : "---"); }
因面向對象的編程思想,都是把這些模擬的類,寫在js文件中。而後頁面一引用js文件就能夠 new User() 了。html
當有幾個頁面 有相互包含關係時,好比 div.Load(url,data,funtion(){}); load動態加載頁面。java
由於這個 被load的頁是同事開發的,因此問題就來了,我一load這個頁面,個人頁面的功能就所有失效。由於我倆都聲明瞭 User 形成了 代碼污染。jquery
好的那麼問題就來了 有沒有一個辦法能夠把他們隔離開來呢。閉包 對 很好的思路。那麼knockout的一堆綁定對閉包的影響??好吧我也不肯定。編程
可是首先要肯定2件事。閉包
第一我就須要先把這個 User給閉包掉,先減小污染。app
function spaceUserInfo() { function User(model) { this.Id = ko.observable(model ? model.Id : "---"); this.Name = ko.observable(model ? model.Name : "---"); }; this.User = User; };
起一個 spaceUserInfo的名字。固然若是這個 spaceUserInfo也被重複了我就沒辦法了。dom
1、js模型閉包函數
第一個前提 咱們都有通用的命名規範,以 space開頭 加上 頁面的名字。基本上同一個項目中 有相互引用關係的頁面這麼處理很難在相撞了。測試
至於 spaceUserInfo 爲何不用 (function(){})(); 這種形式。由於他是匿名啊有木有。我不想把代碼寫得有多高大上,最起碼通俗易懂還好用就好了。
2、頁面js閉包
相信懂閉包的人一眼就看出來了。這個代碼 是這種 (function(){})(); 高大上的寫法。固然咱們這麼寫並非爲了高大上,由於咱們須要當即執行的匿名函數有木有。
首先
傳入 參數。裏面須要 jquery 須要 knock 還須要咱們以前聲明的模擬類。
(function($,ko,space){})($, ko, new spaceUserInfo());
前2個參數不用說 new spaceUserInfo() 這個你們也能懂吧,這裏就至關於 new了一個 class 進去。
匿名方法體中正常書寫代碼。
建立viewModel添加viewModel事件執行ko頁面綁定。很正常的寫法。
<script> (function ($, ko, space) { var _self = this; var viewModel = { User: ko.observable(new space.User()), Users: ko.observableArray( [ new space.User({ Id: '1', Name: '小明' }), new space.User({ Id: '2', Name: '小強' }), new space.User({ Id: '3', Name: '小花' }) ] ), //———————————————————————————— e: {} }; viewModel.e.Add = function () { viewModel.Users.push(new space.User()); }; viewModel.e.show = function (user) { alert(user.Name()); }; //dom ready $(function () { ko.applyBindings(viewModel, $("#pageUserInfo")[0]); }); })($, ko, new spaceUserInfo()); </script>
以上代碼 是js部分。上面實現了閉包,下面纔是重點,怎麼寫才能讓我這個閉包無懈可擊,不須要暴漏任何東西就能爲頁面工做呢?
下面看頁面html代碼。
<div id="pageUserInfo"> <input type="button" name="name" value="模擬外部按鈕" data-bind="click:function(){e.Add()}" /> 測試一個對象<br /> <b>Id:</b><!--ko text:User().Id--><!--/ko--><br /> <b>姓名:</b><!--ko text:User().Name--><!--/ko--><br /> ————————————————————————————————<br /> 測試多個對象<br /> <!--ko foreach:{data:Users,as:'iuser'}--> <b>Id:</b> <!--ko text:iuser.Id--><!--/ko--><br /> <b>姓名:</b> <!--ko text:iuser.Name--><!--/ko--> <input type="text" name="name" data-bind="event:{change:function(){alert($element.value)}}" value=" " /> <a href="javascript:;" data-bind="event:{ mouseover:function(){$parent.e.show(iuser)}}">test</a> <br /> <!--/ko--> </div>
很簡短的幾行代碼。
運行結果以下
因爲上面js底子打得好,因此在模型綁定上直接寫 事件就好了。
值得注意的是 在foreach中綁定event 使用的 是 change 而非 onchange
<input type="text" name="name" data-bind="event:{change:function(){alert($element.value)}}" value=" " />
要function(){} 一下 要否則會被直接執行(不知道爲何)。
咱們在viewmode上聲明瞭全部方法,實現了 viewmode的高內聚。這樣就不用在寫一堆方法來作邏輯了,都寫到內部,就解決了代碼污染。
好的就到這裏吧,我得幹活了。