1. 程式人生 > 程式設計 >js專案中雙向資料繫結的簡單實現方法

js專案中雙向資料繫結的簡單實現方法

目錄
  • 前言
  • 釋出訂閱者模式
    • 結果
    • 呼叫
  • 總結

    前言

    雙向資料繫結 指的是當物件的屬性發生變化時能夠同時改變對應http://www.cppcns.com的UI,反之亦然。換句話說,如果我們有一個user物件,這個物件有一個name屬性,無論何時你對user.name設定了一個新值,UI也會展示這個新的值。同樣的,如果UI包含一個用於資料使用者名稱字的輸入框,輸入一個新值也會導致user物件的name屬性發生相應的改變。

    許多流行的框架,像Ember.,Angular.js或者KnockoutJS都會把雙向資料繫結作為其中的主要特性來宣傳。這並不意味著從頭開始實現它很難,也不意味著當我們需要這種功能的時候,使用這些框架是我們唯一的選擇。內部的潛在思想事實上是相當基礎的,實現它可以歸納為以下三點:

    • 我們需要一種方式確定哪個UI元素繫結在哪個屬性上。
    • 我們需要監控屬性和UI的變化
    • 我們需要把所有繫結的物件和UI元素的變化傳播出去。

    釋出訂閱者模式

    釋出-訂閱模式其實是一種物件間一對多的依賴關係,當一個物件的狀態傳送改變時,所有依賴於它的物件都將得到狀態改變的通知。

    訂閱者(Subscriber)把自己想訂閱的事件註冊(Subscribe)到排程中心(Event Channel),當釋出者(Publisher)釋出該事件(Publish Event)到排程中心,也就是該事件觸發時,由排程中心統一排程(Fire Event)訂閱者註冊到排程中心的處理程式碼。

    結果

    js專案中雙向資料繫結的簡單實現方法

    呼叫

    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 回撥方法
     * [$btn1 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,targetValue);
    }
    pubSub.publish(message,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,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")http://www.cppcns.com {
    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
    &nbshttp://www.cppcns.comp;};
    
    binder.on(uid + ":change",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雙向資料繫結實現內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!