AngularJs是一款优秀的前端JS框架,它实现了将数据模型(data-model)关联到视图(UI)上。但个人认为正是由于它规范性的结构和体系导致使用的时候并不是很灵活。那么如何自己实现一个数据绑定视图的功能呢。
创新互联长期为上千客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为中牟企业提供专业的成都做网站、网站制作,中牟网站改版等技术服务。拥有10年丰富建站经验和众多成功案例,为您定制开发。 设想一下这样的应用场景,当我们修改数据或从服务器接收数据更新现有数据时,如何自动通知所有与数据关联的视图更新显示呢?观察者模式为这种场景提供了很好的解决方案。
观察者模式定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
每个HTML Dom都可以看成一个观察者,他们依赖数据对象,类图如图:
其中Observer类中doms为观察者的标签们,这里一个观察者包含多个标签,避免创建过多的观察者。Subject类作为数据对象的封装,由于javascript没有符号重载的功能,我们设计Setter和Getter的两个方法S()和G()。具体代码如下:
var Observer = Class.extend({ doms:[], subject:null, ctor:function(_tag,_subject){ this.doms = document.querySelectorAll(_tag); this.subject = _subject; this.subject.attach(this); }, update:function(){ for(var i = 0;i < this.doms.length;i++){ var tagName = this.doms[i].nodeName.toLowerCase(); if(this.doms[i].getAttribute('bind-data') != undefined){ var bind = this.doms[i].getAttribute('bind-data'); if(tagName == 'input'||tagName == 'select'){ if(typeof(this.subject.G()) == "object" && Object.prototype.toString.call(this.subject.G()).toLowerCase() == "[object object]" && !this.subject.G().length){ this.doms[i].value = eval("this.subject.G()." + bind); }else{ this.doms[i].value = this.subject.G(); } }else{ if(typeof(this.subject.G()) == "object" && Object.prototype.toString.call(this.subject.G()).toLowerCase() == "[object object]" && !this.subject.G().length){ this.doms[i].innerText = eval("this.subject.G()." + bind); }else{ this.doms[i].innerText = this.subject.G(); } } } } } }); var Subject = Class.extend({ observers:[], data:null, ctor:function(_data){ this.data = _data; }, attach:function(_observer){ this.observers.push(_observer); _observer.update(); }, S:function(expre){ if(typeof(expre) == 'string'){ if(expre.indexOf('=') == -1){ this.data = expre; }else{ if(typeof(this.data) == "object" && Object.prototype.toString.call(this.data).toLowerCase() == "[object object]" && !this.data.length){ eval('this.data.' + expre); }else{ this.data = {}; eval('this.data.' + expre); } } }else{ this.data = expre; } this.notifyAllObservers(); }, G:function(){ return this.data; }, notifyAllObservers(){ for(var i = 0;i < this.observers.length;i++){ this.observers[i].update(); } } });
前端使用的代码如下:
用户名: 密码:用户名:
{username:'hello',password:'world'}
将数据赋值为非JSON对象值
效果如图:
根据结果,我们可以清楚的发现观察者的优势,数据的更新前端开发人员无需再操作Dom就可以更新视图,实现了数据实时更新。当然缺点也显而易见,那就是观察者过多时会数据的更新会过慢。
附件:http://down.51cto.com/data/2368542另外有需要云服务器可以了解下创新互联scvps.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。