js项目中双向数据绑定的简单实现方法

编辑: admin 分类: javascript 发布时间: 2022-01-01 来源:互联网
目录
  • 前言
  • 发布订阅者模式
    • 结果
    • 调用
  • 总结

    前言

    双向数据绑定 指的是当对象的属性发生变化时能够同时改变对应的UI,反之亦然。换句话说,如果我们有一个user对象,这个对象有一个name属性,无论何时你对user.name设置了一个新值,UI也会展示这个新的值。同样的,如果UI包含一个用于数据用户名字的输入框,输入一个新值也会导致user对象的name属性发生相应的改变。

    许多流行的javascript框架,像Ember.js,Angular.js或者KnockoutJS都会把双向数据绑定作为其中的主要特性来宣传。这并不意味着从头开始实现它很难,也不意味着当我们需要这种功能的时候,使用这些框架是我们唯一的选择。内部的潜在思想事实上是相当基础的,实现它可以归纳为以下三点:

    • 我们需要一种方式确定哪个UI元素绑定在哪个属性上。
    • 我们需要监控属性和UI的变化
    • 我们需要把所有绑定的对象和UI元素的变化传播出去。

    发布订阅者模式

    发布-订阅模式其实是一种对象间一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都将得到状态改变的通知。

    订阅者(Subscriber)把自己想订阅的事件注册(Subscribe)到调度中心(Event Channel),当发布者(Publisher)发布该事件(Publish Event)到调度中心,也就是该事件触发时,由调度中心统一调度(Fire Event)订阅者注册到调度中心的处理代码。

    结果

    调用

    html  调用 端 绑定 data-bind-phone="name"

      <ul>  
    
         <li class="block-phone fix bd-bottom">  
    
              <label for="J_verificationPhone" data-bind-phone="tishi"><span>手机号</span></label>  
    
              <input  class="fix1" id="J_verificationPhone" data-bind-phone="name" name="phone"  type="text" />  
    
              <button class="right J_clickTime"  type="button">
    
                <span class="award-messages-btn2 J_messagesBtn1">获取验证码</span>
    
                <span class="award-messages-btn2 J_messagesBtn2 none"><i>60</i>s后重发</span>
    
              </button>
    
         </li>  
    
         <li class="block-verification fix">  
    
              <label for="J_verificationCode"><span>验证码</span></label>  
    
              <input class="fix1" data-bind-code="tishi" id="J_verificationCode" data-bind-phone="name" name="verification-code" class="" type="" />  
    
         </li> 
    
      </ul>  
    
    

    js 调用 看下面代码注释

    /**
     * function verficationCallback 回调方法
     * [$b【文章出处:日本大带宽服务器http://www.558idc.com/jap.html 复制请保留原URL】tn1 description]
     * data-bind-phone="name"
     * @ message {[type]}   发生变化的字段phone
     * @ prop_name {[type]}  字段的value  name
     * @ target {[type]}      目标jsdom对象;
     * @ targetValue {[type]}  目标jsdom对象的value
     */// 监听回调函数,函数会拿到targetvalue 的值, target js dom对象,便于对变化的字段进行操作!!!
    var User= require('../../entry/module/twoWayAudio.js');
    var phone = new User('phone',verficationCallback);
     function verficationCallback(message,prop_name,target,targetValue){
    }
    
    

    引入的源代码 twoWayAudio

    function DataBinder(object_id,verficationCallback){  
    // 创建一个简单的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 !== "") {
    if(verficationCallback){
    var targetValue = target.value;
    verficationCallback (message,prop_name,target,targetValue);
    }
    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,verficationCallback) {  
    var binder = new DataBinder(uid,verficationCallback),
      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;
    }
    module.exports = User;
    // phone.set( "name", "lwl" );  
    // phone.set( "tishi", "提示" );  

    替代解决方案

    上面只是在掩饰双向数据绑定,其实这种需求可以更简单的实现 嘿嘿

     $('.block-phone #phone')[0].oninput=function(){
     console.log($(this))
    }
    
    

    总结

    到此这篇关于js项目中双向数据绑定的简单实现方法的文章就介绍到这了,更多相关js双向数据绑定实现内容请搜索hwidc以前的文章或继续浏览下面的相关文章希望大家以后多多支持hwidc!

    【文章出处:武汉网站优化公司 欢迎转载】