js 双向绑定

//双向绑定实例  <input name="" ng-bind-123="name" />
    function DataBinder( object_id ) {
        // Create a simple PubSub object
        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 = "ng-bind-" + object_id,
          message = object_id + ":keyup",

          changeHandler = function( evt ) {
            var target = evt.target || evt.srcElement, // IE8 compatibility
                prop_name = target.getAttribute( data_attr );

            if ( prop_name && prop_name !== "" ) {
              pubSub.publish( message, prop_name, target.value );
            }
          };

          // Listen to change events and proxy to PubSub
          if ( document.addEventListener ) {
            document.addEventListener( "keyup", changeHandler, false );
          } else {
            // IE8 uses attachEvent instead of addEventListener
            document.attachEvent( "onkeyup", changeHandler );
          }

          // PubSub propagates changes to all bound elements
          pubSub.on( message, function( evt, 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 = {
        // ...
        attributes: {},
        set: function( attr_name, val ) {
          this.attributes[ attr_name ] = val;
          // Use the `publish` method
          binder.publish( uid + ":keyup", attr_name, val, this );
        },
        get: function( attr_name ) {
          return this.attributes[ attr_name ];
        }
      }

      binder.on( uid + ":keyup", function( evt, attr_name, new_val, initiator ) {
        if ( initiator !== user ) {
          user.set( attr_name, new_val );
        }
      });

      return user;
    }

    // javascript
    var user = new User( ‘test‘);
    user.set( "name", "binding" );
时间: 2024-07-31 10:25:11

js 双向绑定的相关文章

Vue.js双向绑定的实现原理

Vue.js最核心的功能有两个,一是响应式的数据绑定系统,二是组件系统.本文仅探究几乎所有Vue的开篇介绍都会提到的hello world双向绑定是怎样实现的.先讲涉及的知识点,再参考源码,用尽可能少的代码实现那个hello world开篇示例. 参考文章:https://segmentfault.com/a/1190000006599500 一.访问器属性 访问器属性是对象中的一种特殊属性,它不能直接在对象中设置,而必须通过defineProperty()方法单独定义. var obj = {

非常简单的js双向绑定框架(二):控制器继承

初衷 上一篇已经实现了数据的双向绑定,但model的控制范围是整个文档,在实际工程中必须要有作用范围,以便做ui模块的拆分. 这一篇,我们希望实现像angularjs一样的控制器继承: 1. 父controller的Model可以在子controller里被访问到 2. 子controller的model不影响父controller 3. controller继承关系在html中指定,而不是js中指定 目标 html里,用isi-controller属性去声明控制器: <body> <d

很easy的js双向绑定框架(二):控制器继承

初衷 上一篇已经实现了数据的双向绑定,但model的控制范围是整个文档.在实际project中必需要有作用范围,以便做ui模块的拆分. 这一篇,我们希望实现像angularjs一样的控制器继承: 1. 父controller的Model能够在子controller里被訪问到 2. 子controller的model不影响父controller 3. controller继承关系在html中指定.而不是js中指定 目标 html里,用isi-controller属性去声明控制器: <body>

Vue.js双向绑定原理

Vue.js最核心的功能有两个,一个是响应式的数据绑定系统,另一个是组件系统.本文仅仅探究双向绑定是怎样实现的.先讲涉及的知识点,再用简化的代码实现一个简单的hello world示例. 一.访问器属性 访问器属性是对象中的一种特殊属性,它不能直接在对象中设置,而必须通过defineProperty()方法单独定义. <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <titl

js双向绑定和地址传递带来的痛苦解决方案之对象拷贝

function cloneObj(obj) { var newObj = {}; if (obj instanceof Array) { newObj = []; } for (var key in obj) { var val = obj[key]; newObj[key] = typeof val === 'object' ? cloneObj(val): val; } return newObj;};

剖析Vue原理&amp;实现双向绑定MVVM

剖析Vue原理&实现双向绑定MVVM vue.js 双向绑定 javascript 邓木琴居然被盗用了 2016年08月16日发布 推荐 24 推荐 收藏 195 收藏,10.6k 浏览 本文能帮你做什么?1.了解vue的双向数据绑定原理以及核心代码模块2.缓解好奇心的同时了解如何实现双向绑定为了便于说明原理与实现,本文相关代码主要摘自vue源码, 并进行了简化改造,相对较简陋,并未考虑到数组的处理.数据的循环依赖等,也难免存在一些问题,欢迎大家指正.不过这些并不会影响大家的阅读和理解,相信看完

vue中的双向绑定

概述 今天对双向绑定感兴趣了,于是去查了下相关文章,发现有用脏检查的(angular.js),有用发布者-订阅者模式的(JQuery),也有用Object.defineProperty的(vue),其中用Object.defineProperty的(vue)特别简单,今天顺便记录下供以后开发时参考,相信对其他人也有用. 我参考了这篇文章:Vue.js双向绑定的实现原理. 类似双向绑定的效果 其实用事件代理就可以实现类似双向绑定的效果,原理是当检测到数据改动时会触发一个keyup事件或者表单的ch

原生js实现数据双向绑定

最近接触了vue,在谈到vue等等的mvvm框架之前,先了解什么是数据双向绑定以及如何利用原生JS实现数据双向绑定 单向数据绑定 指先把模板写好,然后把模板和数据(数据可能来自后台)整合到一起形成HTML代码,然后把这段HTML代码插入到文档流里 缺点:一旦HTML代码生成就没有办法改变,如果有新数据重新传入,就必须重新把模板和数据整合到一起插入到文档流中 数据双向绑定 数据模型和视图之间的双向绑定,用户在视图上的修改会自动同步到数据模型中,同样的,如果数据模型中的值发生变化,也会同步到视图中去

VUE JS 使用组件实现双向绑定

1.VUE 前端简单介绍  VUE JS是一个简洁的双向数据绑定框架,他的性能超过ANGULARJS,原因是实现的机制和ANGULARJS 不同,他在初始化时对数据增加了get和set方法,在数据set时,在数据属性上添加监控,这样数据发生改变时,就会触发他上面的watcher,而ANGULARJS 是使用脏数据检查来实现的. 另外VUEJS 入门比ANGULARJS 简单,中文文档也很齐全. 2.组件实现    在使用vue开发过程中,我们会需要扩展一些组件,在表单中使用,比如一个用户选择器.