zoukankan      html  css  js  c++  java
  • Javascript实现简单的双向绑定

      双向数据绑定指的是将对象属性变化绑定到UI,或者反之。换句话说,如果我们有一个拥有name属性的user对象,当我们给user.name赋予一个新值是UI也会相应的显示新的名字。同样的,如果UI包括了一个输入字段用来输入用户名,输入一个新的值会导致user对象中的那么属性发生变化。

      双向数据绑定底层的思想非常的基本,它可以被压缩成为三个步骤:

    1. 我们需要一个方法来识别哪个UI元素被绑定了相应的属性
    2. 我们需要监视属性和UI元素的变化
    3. 我们需要将所有变化传播到绑定的对象和元素

      虽然实现的方法有很多,但是最简单也是最有效的途径是使用发布者-订阅者模式。思想很简单:我们可以使用自定义的data属性在HTML代码中指明绑定。所有绑定起来的JavaScript对象以及DOM元素都将“订阅”一个发布者对象。任何时候如果JavaScript对象或者一个HTML输入字段被侦测到发生了变化,我们将代理事件到发布者-订阅者模式,这会反过来将变化广播并传播到所有绑定的对象和元素。在这里很多人自然会想到使用jQuery,使用DOM的事件操作来监听UI变化,然后将修改对应的数据字段,再使用on来自定义事件监听数据字段的变化,将变化广播到所有绑定的对象和元素上。本文主要讨论的是使用Javascript来实现双向数据绑定,如果对jQuery实现感兴趣可的话可以参考-JavaScript实现简单的双向数据绑定

      

    这里我们只是对于之前的观察者模式的例子稍作修改,加上了对DOM元素的事件监听:

    function DataBinder(object_id){  
        // 创建一个简单的pubSub对象
        var pubSub = {
                callbacks: {},
                on: function(msg,callback) {
                    this.callbacks[msg] = this.callbacks[msg] || [];
                    this.callbacks[msg].push(callback);
                },
                publish: function(msg) {
                    this.callbacks[msg] = this.callbacks[msg] || [];
                    for (var i = 0,len = this.callbacks[msg].length; i < len; i++) {
                        this.callbacks[msg][i].apply(this,arguments);
                    };
                }
            },
    
            data_attr = "data-bind-" + object_id,
            message   = object_id + ":change",
    
            changeHandler = function(event) {
                var target    = event.target || event.srcElement, // IE8兼容
                    prop_name = target.getAttribute(data_attr);
    
                if (prop_name && prop_name !== "") {
                    pubSub.publish(message,prop_name,target.value);
                }
            };
    
        // 监听事件变化,并代理到pubSub
        if (document.addEventListener) {
            document.addEventListener("keyup",changeHandler,false);
        } else{
            // IE8使用attachEvent而不是addEventListenter
            document.attachEvent("onkeyup",changeHandler);
        };
    
        // pubSub将变化传播到所有绑定元素
        pubSub.on(message,function(event,prop_name,new_val){
            var elements = document.querySelectorAll("[" + data_attr + "=" +prop_name + "]"),
                tag_name;
            for (var i = 0,len = elements.length; i < len; i++) {
                tag_name = elements[i].tagName.toLowerCase();
    
                if (tag_name === "input" || tag_name === "textarea" || tag_name === "select") {
                    elements[i].value = new_val;
                } else{
                    elements[i].innerHTML = new_val;
                };
            };
        })
    
        return pubSub;
    }

    接着定义模型就行了:

    function User(uid) {  
        var binder = new DataBinder(uid),
          user   = {
              attribute : {},
    
              // 属性设置器使用数据绑定器pubSub来发布
              set : function(attr_name,val) {
                  this.attribute[attr_name] = val;
                  binder.publish(uid + ":change",attr_name,val,this);
              },
    
              get : function(attr_name) {
                  return this.attribute[attr_name];
              },
    
              _binder : binder
          };
    
        binder.on(uid + ":change",function(event,attr_name,new_val,initiator) {
            if (initiator !== user) {
                user.set(attr_name,new_val);
            }
        });
    
        return user;
      }

    使用起来就非常简单了,只需要新建模型,通过模型设置字段就行了

    var user = new User( 123 );  
    user.set( "name", "tsy" );  
  • 相关阅读:
    dubbo入门(一)
    java中文件操作《一》
    Unity 游戏框架搭建 2019 (七) 自定义快捷键
    凉鞋:我所理解的框架 【Unity 游戏框架搭建】
    Unity 游戏框架搭建 2019 (六) MenuItem 复用
    Unity 游戏框架搭建 2019 (五) 打开所在文件夹
    Unity 游戏框架搭建 2019 (四) 导出 UnityPackage
    Unity 游戏框架搭建 2019 (三) 生成文件名到剪切板
    Unity 游戏框架搭建 2019 (二) 文本复制到剪切板
    Unity 游戏框架搭建 2019 (一) 简介与第一个示例文件名的生成
  • 原文地址:https://www.cnblogs.com/shytong/p/5080900.html
Copyright © 2011-2022 走看看