angular双向绑定模拟探索
前言
本次探索的demo是基于jquery写的,毕竟jquery提供了强大的选择器,用惯了就离不开它了!angular的双向绑定实在是有点精深,本次探索只实现了文本的双向绑定。
view-model
先看效果:文本框输入内容,model层数据也同步过来了
model-view
先看效果:js改变model层数据,视图也立即随之变化
上我的demo
<!doctype html> <html lang="en" data-swq-app = 'app'> <head> <meta charset="utf-8"> <title>title</title> <script src="./js/jquery-1.9.1.min.js"></script> </head> <body> <input type="text" data-swq-model="name"> <input type="text" data-swq-model="age"> <div>name:<span data-swq-bind="name"></span></div> <div>age:<span data-swq-bind="age"></span></div> <script> (function(window){ //模仿angular的双向绑定 //需要一个发布者,也就是angular里面的$scope的存在,这里我取我的大名swq,是个对象 //需要订阅者数据容器 var swqarray = []; //订阅者数据容器 var swqnamesarray = ['name','age']; //存放订阅者标识容器,这边写死,实际上肯定需要动态获取 window.swq ={ scantag : function (){ var swqcontroller = $('[data-swq-app]:first'); // view层需要和model层绑定的元素进行事件绑定 var allmodelview = swqcontroller.find('[data-swq-model]'); allmodelview.each(function(){ $(this).on('keyup',function(event){ var targetbind = $(this).data('swqmodel'); var value = $(this).val(); if(targetbind && targetbind.length > 0){ swq[targetbind] = value; } }); }); // model层需要劫持绑定的进行绑定 $.each(swqnamesarray,function(index,value){ notifyproperty(value); }) } }; //数据的变化需要反映到视图上,因此要监听到数据的变化,js原生的defineproperty给我们提供了监听的可能,劫持更改数据,思路有点类似前端路由的实现思路,我监听到你某个操作但是我不做你的功能,我自己定义该做的事 function notifyproperty(name){ object.defineproperty(swq,name,{ //劫持到set方法 set : function(newvalue){ swqarray[name] = newvalue; // 实现model-view的同步 var $target = $('[data-swq-bind = "'+name+'"],[data-swq-model = "'+name+'"]'); if($target){ $target.each(function(){ var tagname = $(this)[0].tagname.tolowercase(); if(tagname == 'input' || tagname =='select' || tagname =='textarea'){ $(this).val(newvalue) }else{ $(this).text(newvalue) } }) } }, //劫持到get方法,因为get方法已经被劫持,所以比如我们劫持了swq.name,那么swq.name就没有值了,所以我们给它返回值,返回值是存在订阅者数据容器里面的 get : function(){ return swqarray[name]; } }); } })(window); swq.scantag();//初始化,进行双向绑定 // 尚未实现的功能 ; // 1.动态获取需要进行双向绑定的name // 2.只实现了text文本的绑定,对象的绑定需要递归 // 3.脏查询机制还未实现,就是我们某些js后增加的需要双向绑定的name,没办法进行双向绑定了 // 4.angular双花括号解析表达式未实现<br>// 5.感觉还差得远,哪位大神看到有成熟的demo记得给链接!!! </script> </body> </html>
demo解读
核心其实就是js原生的defineproperty。在这之前,我们需要知道,我们在给某个对象添加和获取属性和方法时其实它底层是调用了set和get方法,比如obj.name="名字",这里是调用了set方法,obj.name这里是调用了get方法。
因此,我们可以劫持js的这两个底层方法
object.defineproperty(obj,attribute,{set:function(newvlaue){//dosomething},get:function(){//dosomething}})
obj是我们的model对象,attribute就是我们要劫持的需要双向绑定的name,set就是设置属性时底层调用的方法,get就是获取属性时底层调用的方法因为我们劫持了这两个底层方法,我们可以做我们想做的事,但是同时我们也破坏了它本身的设置和获取功能,因此我这里是把订阅者的数据都是存在一个数组里面的,我还声明了一个数组用来保存所有需要进行双向绑定的name,比较low的是我这边是写死的,实际情况下肯定是要动态获取所有需要双向绑定的name的
结言
本人小菜对前端技术很感兴趣,有大神路过给点指点,我也可以关注下各位大神的博客,希望可以学到更多的东西!!!谢谢
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读
-
利用angular.copy取消变量的双向绑定与解析
-
jquery,js简单实现类似Angular.js双向绑定
-
Angular指令封装jQuery日期时间插件datetimepicker实现双向绑定示例
-
Angular和Vue双向数据绑定的实现原理(重点是vue的双向绑定)
-
angular,vue,react的基本语法—双向数据绑定、条件渲染、列表渲染、angular小案例
-
解决angular2在双向数据绑定时[(ngModel)]无法使用的问题
-
angular4自定义组件非input元素实现ngModel双向数据绑定的方法
-
div实现自适应高度的textarea实现angular双向绑定
-
Angular2实现自定义双向绑定属性
-
自定义Angular指令与jQuery实现的Bootstrap风格数据双向绑定的单选与多选下拉框