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 相关文章推荐
JQuery,Extjs,YUI,Prototype,Dojo 等JS框架的区别和应用场景简述
Apr 15 Javascript
JavaScript高级程序设计 阅读笔记(二十一) JavaScript中的XML
Sep 14 Javascript
javascript中[]和{}对象使用介绍
Mar 20 Javascript
javascript强大的日期函数代码分享
Sep 04 Javascript
jquery简单实现鼠标经过导航条改变背景图
Dec 17 Javascript
Mac OS X 系统下安装和部署Egret引擎开发环境
Sep 03 Javascript
javascript根据时间生成m位随机数最大13位
Oct 30 Javascript
jQuery表格行上移下移和置顶的实现方法
Oct 08 Javascript
jQuery动态增减行的实例代码解析(推荐)
Dec 05 Javascript
jQuery实现简单的计时器功能实例分析
Aug 29 jQuery
在Vue项目中使用d3.js的实例代码
May 01 Javascript
Vue3.0的优化总结
Oct 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
星际争霸 Starcraft 编年史
2020/03/14 星际争霸
一个PHP缓存类代码(附详细说明)
2011/06/09 PHP
修改PHP的memory_limit限制的方法分享
2012/02/21 PHP
ThinkPHP CURD方法之field方法详解
2014/06/18 PHP
PHP封装分页函数实现文本分页和数字分页
2014/10/23 PHP
php图片的二进制转换实现方法
2014/12/15 PHP
PHP实现动态web服务器方法
2015/07/29 PHP
PHP 将数组打乱 shuffle函数的用法及简单实例
2016/06/17 PHP
浅谈PHP安全防护之Web攻击
2017/01/03 PHP
jQuery ajax+PHP实现的级联下拉列表框功能示例
2019/02/12 PHP
php学习笔记之字符串常见操作总结
2019/07/16 PHP
jQuery.clean使用方法及思路分析
2013/01/07 Javascript
JavaScript 开发工具webstrom使用指南
2014/12/09 Javascript
JS实现自动定时切换的简洁网页选项卡效果
2015/10/13 Javascript
浅谈js中字符和数组一些基本算法题
2016/08/15 Javascript
Bootstrap中datetimepicker使用小结
2016/12/28 Javascript
js案例之鼠标跟随jquery版(实例讲解)
2017/07/21 jQuery
js+html实现点名系统功能
2019/11/05 Javascript
jquery ajax 请求小技巧实例分析
2019/11/11 jQuery
javascript canvas API内容整理
2020/02/16 Javascript
vue+swiper实现左右滑动的测试题功能
2020/10/30 Javascript
Python的time模块中的常用方法整理
2015/06/18 Python
在Mac OS上搭建Python的开发环境
2015/12/24 Python
python 时间戳与格式化时间的转化实现代码
2016/03/23 Python
Python爬取个人微信朋友信息操作示例
2018/08/03 Python
Python Django给admin添加Action的方法实例详解
2019/04/29 Python
Python 的字典(Dict)是如何存储的
2019/07/05 Python
Python Pandas 箱线图的实现
2019/07/23 Python
New Balance天猫官方旗舰店:始于1906年,百年慢跑品牌
2017/11/15 全球购物
毕业生个人投资创业计划书
2014/01/04 职场文书
霸王洗发水广告词
2014/03/14 职场文书
爱国主义教育活动总结
2014/05/07 职场文书
推广活动策划方案
2014/08/23 职场文书
公司委托书格式范本
2014/09/16 职场文书
2014年企业工会工作总结
2014/11/12 职场文书
Promise面试题详解之控制并发
2021/05/14 面试题