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 相关文章推荐
SinaEditor使用方法详解
Dec 28 Javascript
javascript判断chrome浏览器的方法
Mar 26 Javascript
使用CDN和AJAX加速WordPress中jQuery的加载
Dec 05 Javascript
学习JavaScript设计模式之观察者模式
Apr 22 Javascript
快速掌握Node.js事件驱动模型
Mar 21 Javascript
JS实现简单易用的手机端浮动窗口显示效果
Sep 07 Javascript
js判断价格,必须为数字且不能为负数的实现方法
Oct 07 Javascript
Popup弹出框添加数据实现方法
Oct 27 Javascript
vue 实现边输入边搜索功能的实例讲解
Sep 16 Javascript
在微信小程序中保存网络图片
Feb 12 Javascript
vue组件定义,全局、局部组件,配合模板及动态组件功能示例
Mar 19 Javascript
基于element-ui对话框el-dialog初始化的校验问题解决
Sep 11 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判断是否为空的几个函数对比
2015/04/21 PHP
PHP实现的一致性哈希算法完整实例
2015/11/14 PHP
PHP判断一个变量是否为整数、正整数的方法示例
2019/09/11 PHP
jquery实用代码片段集合
2010/08/12 Javascript
用Javascript实现Sleep暂停功能代码
2010/09/03 Javascript
javascript:void(0)的问题使用探讨
2014/04/10 Javascript
滚动条响应鼠标滑轮事件实现上下滚动的js代码
2014/06/30 Javascript
js图片轮播特效代码分享
2015/09/07 Javascript
jQuery实现弹出带遮罩层的居中浮动窗口效果
2016/09/12 Javascript
用js实现博客打赏功能
2016/10/24 Javascript
关于JS与jQuery中的文档加载问题
2017/08/22 jQuery
JS实现移动端双指缩放和旋转方法
2019/12/13 Javascript
JS数组的高级使用方法示例小结
2020/03/14 Javascript
[48:12]Secret vs Optic Supermajor 胜者组 BO3 第三场 6.4
2018/06/05 DOTA
[00:58]PWL开团时刻DAY5——十人开雾0换5
2020/11/04 DOTA
linux系统使用python监测系统负载脚本分享
2014/01/15 Python
python获得两个数组交集、并集、差集的方法
2015/03/27 Python
使用Python脚本对Linux服务器进行监控的教程
2015/04/02 Python
Python之ReportLab绘制条形码和二维码的实例
2018/01/15 Python
对Tensorflow中的变量初始化函数详解
2018/07/27 Python
使用Python抓取豆瓣影评数据的方法
2018/10/17 Python
python中将正则过滤的内容输出写入到文件中的实例
2018/10/21 Python
pandas通过索引进行排序的示例
2018/11/16 Python
python GUI库图形界面开发之PyQt5动态加载QSS样式文件
2020/02/25 Python
python打包多类型文件的操作方法
2020/09/21 Python
Alexandre Birman美国官网:亚历山大·伯曼
2019/10/30 全球购物
Lancer Skincare官方网站:抗衰老皮肤护理
2020/11/20 全球购物
C语言中一个结构不能包含指向自己的指针吗
2012/05/25 面试题
英语专业毕业生自荐信
2013/10/28 职场文书
护士的岗位职责
2013/12/04 职场文书
生产助理岗位职责
2014/06/18 职场文书
2015年小学数学教师工作总结
2015/05/20 职场文书
安全教育培训制度
2015/08/06 职场文书
纯html+css实现打字效果
2021/08/02 HTML / CSS
排查Tomcat进程假死的问题
2022/05/06 Servers
正则表达式基础与常用验证表达式
2022/06/16 Javascript