angular双向绑定模拟探索


Posted in Javascript onDecember 26, 2016

前言
本次探索的demo是基于jquery写的,毕竟jquery提供了强大的选择器,用惯了就离不开它了!angular的双向绑定实在是有点精深,本次探索只实现了文本的双向绑定。

View-Model

先看效果:文本框输入内容,model层数据也同步过来了

angular双向绑定模拟探索

Model-View

先看效果:js改变model层数据,视图也立即随之变化

angular双向绑定模拟探索

上我的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的

结言

本人小菜对前端技术很感兴趣,有大神路过给点指点,我也可以关注下各位大神的博客,希望可以学到更多的东西!!!谢谢

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
网站上面有这种切换效果
Jun 26 Javascript
JavaScript 闭包在封装函数时的简单分析
Nov 28 Javascript
javascript中的undefined和not defined区别示例介绍
Feb 26 Javascript
JavaScript获取当前页面上的指定对象示例代码
Feb 28 Javascript
JavaScript Array对象扩展indexOf()方法
May 09 Javascript
基于javascript代码检测访问网页的浏览器呈现引擎、平台、Windows操作系统、移动设备和游戏系统
Dec 03 Javascript
javascript实现延时显示提示框特效代码
Apr 27 Javascript
轻松实现jquery选项卡切换效果
Oct 10 Javascript
JS实现图片放大镜插件详解
Nov 06 Javascript
详解React Native 采用Fetch方式发送跨域POST请求
Nov 15 Javascript
Vux+Axios拦截器增加loading的问题及实现方法
Nov 08 Javascript
理理Vue细节(推荐)
Apr 16 Javascript
jquery Banner轮播选项卡
Dec 26 #Javascript
Javascript中常用类型的格式化方法小结
Dec 26 #Javascript
Angular的自定义指令以及实例
Dec 26 #Javascript
如何提高javascript加载速度
Dec 26 #Javascript
JS实现一次性弹窗的方法【刷新后不弹出】
Dec 26 #Javascript
javascript实现去除HTML标签的方法
Dec 26 #Javascript
解析JavaScript实现DDoS攻击原理与保护措施
Dec 26 #Javascript
You might like
PHP新手上路(五)
2006/10/09 PHP
php单一接口的实现方法
2015/06/20 PHP
php简单获取复选框值的方法
2016/05/11 PHP
Thinkphp3.2.3整合phpqrcode生成带logo的二维码
2016/07/21 PHP
jquery和雅虎的yql服务实现天气预报服务示例
2014/02/08 Javascript
JS组件系列之使用HTML标签的data属性初始化JS组件
2016/09/14 Javascript
canvas实现手机端用来上传用户头像的代码
2016/10/20 Javascript
Json对象和字符串互相转换json数据拼接和JSON使用方式详细介绍(小结)
2016/10/25 Javascript
ReactJs实现树形结构的数据显示的组件的示例
2017/08/18 Javascript
详解Angular5 服务端渲染实战
2018/01/04 Javascript
vue做移动端适配最佳解决方案(亲测有效)
2018/09/04 Javascript
AngularJS 监听变量变化的实现方法
2018/10/09 Javascript
node实现socket链接与GPRS进行通信的方法
2019/05/20 Javascript
详解JWT token心得与使用实例
2019/08/02 Javascript
javascript设计模式 ? 装饰模式原理与应用实例分析
2020/04/14 Javascript
openlayers实现图标拖动获取坐标
2020/09/25 Javascript
Python操作json数据的一个简单例子
2014/04/17 Python
Python实现的简单hangman游戏实例
2015/06/28 Python
Python3 中文文件读写方法
2018/01/23 Python
python 读取目录下csv文件并绘制曲线v111的方法
2018/07/06 Python
Python如何筛选序列中的元素的方法实现
2019/07/15 Python
基于Python词云分析政府工作报告关键词
2020/06/02 Python
python3实现简单飞机大战
2020/11/29 Python
css3实现图片遮罩效果鼠标hover以后出现文字
2013/11/05 HTML / CSS
美国最大的电子宠物训练产品制造商:PetSafe
2018/10/12 全球购物
linux面试题参考答案(6)
2014/08/29 面试题
采购主管的岗位职责
2013/12/17 职场文书
公积金转移接收函
2014/01/11 职场文书
2014年教师党员公开承诺书
2014/05/28 职场文书
租房安全协议书
2014/08/20 职场文书
银行会计主管岗位职责
2014/10/01 职场文书
市场部岗位职责
2015/02/12 职场文书
预备党员表决心的话
2015/09/22 职场文书
创业计划书之韩国烧烤店
2019/09/19 职场文书
python基础之错误和异常处理
2021/10/24 Python
MySQL控制流函数(-if ,elseif,else,case...when)
2022/07/07 MySQL