写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的高内聚。这样就不用在写一堆方法来作逻辑了,都写到内部,就解决了代码污染。
好的就到这里吧,我得干活了。