国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

從單向到雙向數(shù)據(jù)綁定

laoLiueizo / 711人閱讀

摘要:而實現(xiàn)這種的可以有雙向數(shù)據(jù)綁定單向數(shù)據(jù)流的形式。單向數(shù)據(jù)綁定,就是綁定事件,比如綁定這些事件,只要觸發(fā)事件,立刻執(zhí)行對應(yīng)的函數(shù)。

本文來自我的github 0.前言

用戶最滿意的,無非就是界面的操作能實事反應(yīng)到數(shù)據(jù)。而實現(xiàn)這種的可以有雙向數(shù)據(jù)綁定、單向數(shù)據(jù)流的形式。雙向數(shù)據(jù)綁定是,ui行為改變model層的數(shù)據(jù),model層的數(shù)據(jù)變了也能反映到ui上面。比如點擊按鈕,數(shù)字data+1,如果我們自己在控制臺再給data+1,那么v層也能馬上看見這個變化。而單向數(shù)據(jù)流就不同了,我們只有ui行為改變,data就改變并馬上反饋到v層,而我們自己在控制臺改變data這個值,v層居然不變(model是已經(jīng)變了并沒有反應(yīng)),只能等到下一次ui行為改變,帶上這個data結(jié)果一起處理。僅僅在V層的單向數(shù)據(jù),真的能滿足用戶需求?數(shù)據(jù)很龐大的時候,雙綁性能如何?其實,每一種都有每一種的適用場景,還是那句話,脫離實際場景談性能,就是扯淡

1.單向數(shù)據(jù)(代表:react)

一般的過程:ui行為→觸發(fā)action→改變數(shù)據(jù)state→mumtation再次渲染ui界面,通常就是基于view層,一個很簡單的例子:
html部分:


js部分:

var str = ""
a.innerHTML = str//初始化
ipt.oninput = function(){//點擊觸發(fā)action
    str = ipt.value//改變state狀態(tài)值
    a.innerHTML = str//重新渲染
}

但是如果在控制臺獲取input這個dom,在設(shè)置value,不會馬上反映,只能等下一次帶著這個結(jié)果一起作用。這僅僅是V->M的過程

我們再做一個超級簡單的雙綁:
html部分:


js部分:

var $scope = {
    data:""
}
a.innerHTML = ""
setInterval(function(){
    a.innerHTML = $scope.data
},60)
ipt.oninput = function(){
     $scope.data = ipt.value
}

這里除了單向數(shù)據(jù)綁定,當(dāng)你改變$scope.data,p標(biāo)簽的內(nèi)容也是會馬上改變。因為用了定時器,他會異步地將數(shù)據(jù)反映上去。

2.觀察者模式

首先,我們先訂閱事件,比如事件‘a(chǎn)’,回調(diào)函數(shù)是function (){console.log(1)},訂閱后,如果事件‘a(chǎn)’被觸發(fā)了,就調(diào)用回調(diào)函數(shù)。

function Event(){
    this.list=[],
    this.on=function(key,cb){//訂閱事件
        if(!this.list[key]){
            this.list[key] = []
        }
        this.list[key].push(cb)
    },
    this.emit = function(){//觸發(fā)事件
        var key = Array.prototype.shift.call(arguments)
        var e = this.list[key]
        if(!e){
            return
        }
        var args = Array.prototype.slice.call(arguments)
        for(var i = 0;i

嘗試一下:

var a = new Event()
a.on("a",function(x){console.log(x)})
a.emit("a",1)//1

這樣子,在1中單向數(shù)據(jù)的小例子,首先我們on里面加入事件a,回調(diào)是a.innerHTML = str,然后我們可以在改變model層的時候,順便觸發(fā)一下(emit(‘a(chǎn)’)),不就可以做到M->V的反映了嗎?

對的,是行得通,可是這都是死的,也不能自動讓他雙向數(shù)據(jù)綁定,所以我們借用js底層的Object.defineproperty。

3.雙綁的中間樞紐——Object.defineproperty(代表:vue)

在第二篇文章已經(jīng)講過,這里再重復(fù)一次:

var obj = {name:"pp"}
console.log(obj.name)//pp
Object.defineProperty(obj,"name",{
      get:function(){
        return 1
      },
      set:function(newVal){
        console.log(newVal)
      }
    })
console.log(obj.name)//1
obj.name = 2;//2
console.log(obj.name)//1

這是vue雙綁的核心思想,v層能讓m層變了,m層也能讓v層變了,只是不能互相關(guān)聯(lián)起來,不能做到改變一個層另一個層也能改變。但是,現(xiàn)在就可以了。
html部分:


//js:
var data = {
    str:""
}
a.innerHTML = data.str//初始化
function E (){
    this.list=[],
    this.on=function(key,cb){//訂閱事件
        if(!this.list[key]){
            this.list[key] = []
        }
        this.list[key].push(cb)
    },
    this.emit = function(){//觸發(fā)事件
        var key = Array.prototype.shift.call(arguments)
        var e = this.list[key]
        if(!e){
            return
        }
        var args = Array.prototype.slice.call(arguments)
        for(var i = 0;i

這下,不僅僅是有改變input的內(nèi)容的單向的數(shù)據(jù)綁定,而且你還可以去控制臺改變data.str=1,p標(biāo)簽的內(nèi)容馬上變成1,實現(xiàn)了雙向數(shù)據(jù)綁定。
我們的例子其實不用觀察者模式都可以實現(xiàn)雙綁,但是在實際應(yīng)用中肯定也不可以不用觀察者模式,為了代碼可讀性和可維護(hù)性以及拓展性。具體的v-model實現(xiàn)在前面文章已經(jīng)講過

點擊跳轉(zhuǎn)文章

到這里,你大概比較深入理解雙向數(shù)據(jù)綁定是什么了。網(wǎng)上有很多人有vue雙綁demo,但是他們有一部分是僅僅單向綁定的,不妨手動去控制臺改一下那個核心綁定的數(shù)據(jù),V層的顯示內(nèi)容能馬上變化的就是雙綁、不能馬上有變化的只是單向數(shù)據(jù)

4. 臟值檢測(代表:angular1) 前面說的定時器雙綁是扯淡

前面特地埋了個坑,關(guān)于Angular臟檢查,并不是一些人想象的那樣子用定時器周期性進(jìn)行臟檢測(我前面寫的那個超級簡單的雙綁就是人們傳聞的angular)

只有當(dāng)UI事件,ajax請求或者 timeout 等異步事件,才會觸發(fā)臟檢查。而我們前面的vue,當(dāng)我們在控制臺改了數(shù)據(jù),就可以馬上反映到v層。angular并沒有這個操作,也沒有意義。因為雙綁的M->V一般就是基于ui行為、定時器、ajax這些異步動作,所以這就知道為什么ng-model只能對表單有效了。想做到像vue那樣的極致雙綁,能夠在控制臺改個數(shù)據(jù)就改變視圖的,大概就只有defineproperty和定時器輪詢了吧。

在angular1中,私有變量以$$開頭,$$watch是一個存放很多個綁定的對象的數(shù)組,用$watch方法來添加的,每一個被綁定的對象屬性是:變量名、變量舊值、一個函數(shù)(用來返回變量新值)、檢測變化的回調(diào)函數(shù)。
對于為什么使用一個函數(shù)來記錄新值(類似vue的computed)?這樣子可以每次調(diào)用都得到數(shù)據(jù)上最新的值,如果把這個值寫死,不就是不會變化了嗎?這是監(jiān)控函數(shù)的一般形式:從作用域獲取值再返回。
接著我們對$scope的非函數(shù)數(shù)據(jù)進(jìn)行綁定,再到 核心的$digest循環(huán),對于每一個$$watch里面的每一個watch,我們使用 getNewValue() 并且把scope實例 傳遞進(jìn)去,得到數(shù)據(jù)最新值。然后和上一次值進(jìn)行比較,如果不同,那就調(diào)用 getListener,同時把新值和舊值一并傳遞進(jìn)去。 最終,我們把last屬性設(shè)置為新返回的值,也就是最新值。$digest里會調(diào)用每個getNewValue(),因此,最好關(guān)注監(jiān)聽器的數(shù)量,還有每個獨立的監(jiān)控函數(shù)或者表達(dá)式的性能。
在作用域上添加數(shù)據(jù)本身不會有性能問題。如果沒有監(jiān)聽器在監(jiān)控某個屬性,它在不在作用域上都無所謂。$digest并不會遍歷作用域的屬性,它遍歷的是監(jiān)聽器。一旦將數(shù)據(jù)綁定到UI上,就會添加一個監(jiān)聽器。
最后,我們需要將新的變量值更新到DOM上,只要加上ng的指令,并解釋,觸發(fā)$digest循環(huán)即可
html:

    
    

js:

function Scope(){
        this.$$watchers=[];         //監(jiān)聽器
    }

    Scope.prototype.$watch=function(name,exp,listener){
        this.$$watchers.push({
            name:name,                              //數(shù)據(jù)變量名
            last:"",                                //數(shù)據(jù)變量舊值
            newVal:exp,                             //返回數(shù)據(jù)變量新值的函數(shù)
            listener:listener || function(){}       //監(jiān)聽回調(diào)函數(shù),變量“臟”時觸發(fā)
        })
    }

    Scope.prototype.$digest=function(){
        var bindList = document.querySelectorAll("[ng-bind]");      //獲取所有含ng-bind的DOM節(jié)點
        var dirty=true;
        while(dirty){
            dirty=false;
            for(var i=0;i

當(dāng)然,還會有一個問題,當(dāng)有兩個$watch循環(huán)監(jiān)聽(watch1監(jiān)聽watch2watch2監(jiān)聽watch1),一個$digest循環(huán)執(zhí)行很多次,而且是多余操作(并且可能把瀏覽器炸了)。

var scope = new $scope();
scope.a = 5;
scope.b = 1;
scope.$watch("a", function(scope) {
  return scope[this.name]
 },
 function(newValue, oldValue) {
  scope.b ++;
 })
 
scope.$watch("b", function(scope) {
  return scope[this.name]
 },
 function(newValue, oldValue) {
  scope.a ++;
 })

angular有一個概念叫迭代的最大值:TTL(short for Time To Live)。這個值默認(rèn)是10。因為digest經(jīng)常被執(zhí)行,而且每個digest運行了所有的$watch,再加上用戶一般不會創(chuàng)建10個以上鏈狀的監(jiān)聽器。
angular的處理辦法是

$scope.prototype.$digest = function() {
       ?var dirty = true;
?       var checkTimes = 0;
        ?while(dirty) {
?           dirty = this.$$digestOnce();
?           checkTimes++;
            ?if(checkTimes>10 &&dirty){
??                 throw new Error();
        ?}
    ?};
};

對于雙綁,如果是大循環(huán),循環(huán)改變一個值,vue的setter這種即時性的雙綁就會在每一次循環(huán)都跑一次,而angular1的臟檢測這種慢性雙綁你可以控制在循環(huán)后才一次跑一次,性能取舍就看實際場景吧。

單向數(shù)據(jù)流和單向數(shù)據(jù)綁定是什么區(qū)別呢?

單向數(shù)據(jù)流,你得按照他的順序辦事。比如我們假設(shè)有一個這樣的生命周期:1.從data里面讀取數(shù)據(jù)2.ui行為(如果沒有ui行為就停在這里等他有了為止)3.觸發(fā)data更新4.再回到步驟1

改了一個數(shù),v層不能反回頭來找他來更新v層視圖(從步驟2跳回去1),你得等下一個循環(huán)(轉(zhuǎn)了一圈)的步驟1才能更新視圖。react都是這樣子,你得setState觸發(fā)更新,如果你this.state = {...},是沒用的,他一直不變。

單向數(shù)據(jù)綁定,就是綁定事件,比如綁定oninput、onchange、storage這些事件,只要觸發(fā)事件,立刻執(zhí)行對應(yīng)的函數(shù)。所以,不要再說一個input綁一個oninput,然后回調(diào)改變一個視圖層數(shù)據(jù)就叫他雙向數(shù)據(jù)綁定了。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/94359.html

相關(guān)文章

  • 前端MVVM模式及其在Vue和React中的體現(xiàn)

    摘要:在模式中一般把層算在層中,只有在理想的雙向綁定模式下,才會完全的消失。層將通過特定的展示出來,并在控件上綁定視圖交互事件,一般由框架自動生成在瀏覽器中。三大框架的異同三大框架都是數(shù)據(jù)驅(qū)動型的框架及是雙向數(shù)據(jù)綁定是單向數(shù)據(jù)綁定。 MVVM相關(guān)概念 1) MVVM典型特點是有四個概念:Model、View、ViewModel、綁定器。MVVM可以是單向綁定也可以是雙向綁定甚至是不綁...

    沈建明 評論0 收藏0
  • [譯] 你真的知道 Angular 單向數(shù)據(jù)流嗎

    摘要:所以,單向數(shù)據(jù)流的意思是指在變更檢測期間屬性綁定變更的架構(gòu)。相反,輸出綁定過程并沒有在變更檢測期間內(nèi)運行,所以它沒有把單向數(shù)據(jù)流轉(zhuǎn)變?yōu)殡p向數(shù)據(jù)流。說的單向數(shù)據(jù)流說的是服務(wù)層,而不是視圖層嗷。 原文鏈接: Do you really know what unidirectional data flow means in?Angular 關(guān)于單向數(shù)據(jù)流,還可以參考這篇文章,且文中還有 y...

    fox_soyoung 評論0 收藏0
  • Flux用過了,Redux也用過了,還是覺得不順手?要不要自己造一個?

    摘要:前言很多同學(xué)用過了,也用過了,但還是覺得不稱心要不要自己造一個一百行來代碼就基本搞定,其實,自己造的框架實不實用,并不重要,重要的是思想。總線根據(jù)路由表,調(diào)用對應(yīng)的進(jìn)行處理。 1 前言 很多同學(xué)用過了Flux,也用過了Redux,但還是覺得不稱心?要不要自己造一個?一百行來代碼就基本搞定,So easy, so good! 其實,自己造的框架實不實用,并不重要,重要的是思想。有了設(shè)計框...

    李世贊 評論0 收藏0
  • 【教學(xué)向】150行代碼教你實現(xiàn)一個低配版的MVVM庫(1)- 原理篇

    摘要:模塊則負(fù)責(zé)維護(hù),以及各個模塊間的調(diào)度思考題了解了的實現(xiàn)機(jī)制,你能否自己動手也試著用百來行代碼實現(xiàn)一個庫呢好了本教程第一部分設(shè)計篇就寫到這里,具體請移步下一篇教學(xué)向行代碼教你實現(xiàn)一個低配版的庫代碼篇我會用給出一版實現(xiàn)。 適讀人群 本文適合對MVVM有一定了解(如有主流框架ng,vue等使用經(jīng)驗配合本文服用則效果更佳),雖然會用這類框架,但是對框架底層核心實現(xiàn)又不太清楚,或者能說出個所以然...

    selfimpr 評論0 收藏0
  • Vue源碼解析:雙向綁定原理

    摘要:無論是還是都提倡單向數(shù)據(jù)流管理狀態(tài),那我們今天要談的雙向綁定是否和單向數(shù)據(jù)流理念有所違背我覺得不是,從上篇文章語法樹轉(zhuǎn)函數(shù)了解到,雙向綁定,實質(zhì)是的單向綁定和事件偵聽的語法糖。源碼解析今天涉及到的代碼全在文件夾下。 通過對 Vue2.0 源碼閱讀,想寫一寫自己的理解,能力有限故從尤大佬2016.4.11第一次提交開始讀,準(zhǔn)備陸續(xù)寫: 模版字符串轉(zhuǎn)AST語法樹 AST語法樹轉(zhuǎn)rend...

    oliverhuang 評論0 收藏0

發(fā)表評論

0條評論

閱讀需要支付1元查看
<