成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

angular1學(xué)習(xí)筆記,view model 的同步過程

Forelax / 956人閱讀

摘要:但實(shí)際上這時(shí)程序并沒有計(jì)算手續(xù)費(fèi)。經(jīng)過排查并查閱文檔之后,發(fā)現(xiàn)是的問題。本文沒有具體介紹和管道,關(guān)于這部分可以參考文中給出的鏈接

事情起源于在項(xiàng)目中遇到的一個(gè)小問題:項(xiàng)目中需要一個(gè)輸入框輸入賣出產(chǎn)品數(shù)量,并且在用戶輸入后根據(jù)輸入數(shù)據(jù)計(jì)算手續(xù)費(fèi)。很自然的我用了ng-model和ng-change,并且一般情況下沒什么問題。問題是:輸入框下還有一個(gè)按鈕是全部賣出,點(diǎn)擊這個(gè)按鈕程序會(huì)自動(dòng)設(shè)置賣出額。但實(shí)際上這時(shí)程序并沒有計(jì)算手續(xù)費(fèi)。
經(jīng)過排查并查閱文檔之后,發(fā)現(xiàn)是ng-change的問題。Angular關(guān)于ng-change的官方文檔的提示是:
The expression is not evaluated when the value change is coming from the model.
ng-change的源碼也很簡(jiǎn)單:

  var ngChangeDirective = valueFn({
      restrict: "A",
      require: "ngModel",
      link: function(scope, element, attr, ctrl) {
        ctrl.$viewChangeListeners.push(function() {
          scope.$eval(attr.ngChange);
        });
      }
    });

從中我們也可以看出ng-change只做了view到model的監(jiān)聽。所以當(dāng)我們直接在js中修改ng-model的變量時(shí)并不會(huì)觸發(fā)ng-change。
問題找到了,解決方案也不難,放棄ng-change,改用$watch就行了。
但是就這么結(jié)束了嗎?一個(gè)變量從view變化開始到同步更新到model到底經(jīng)歷了什么呢?反過來呢,是一樣的嗎?
所以我又去看了看ng-model的源碼,并沒有什么收獲,不過意外的了解到了這么個(gè)點(diǎn):
ng-change是在model值變化之前執(zhí)行的。ng-model源碼中有這么個(gè)函數(shù):

function setupModelWatcher(ctrl) {
  // model -> value
  // !!!Note: we cannot use a normal scope.$watch as we want to detect the following:
  // !!!1. scope value is "a"
  // !!! 2. user enters "b"
  // !!!3. ng-change kicks in and reverts scope value to "a"
  //    -> scope value did not change since the last digest as
  //       ng-change executes in apply phase
  // !!!4. view should be changed back to "a"
  ctrl.$$scope.$watch(function ngModelWatch(scope) {
    var modelValue = ctrl.$$ngModelGet(scope);

    // if scope model value and ngModel value are out of sync
    // This cannot be moved to the action function, because it would not catch the
    // case where the model is changed in the ngChange function or the model setter
    if (modelValue !== ctrl.$modelValue &&
      // checks for NaN is needed to allow setting the model to NaN when there"s an asyncValidator
      // eslint-disable-next-line no-self-compare
      (ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue)
    ) {
      ctrl.$$setModelValue(modelValue);
    }

    return modelValue;
  });
}

里面的注釋解釋了為什么變量model值的修改要在ng-change之后,因?yàn)閚g-change中很可能會(huì)把變量的值又修改回去,這樣變量值事實(shí)上就并沒改變(寫api真的是什么情況都要考慮到?。。。jP(guān)于這一點(diǎn),以及前面的問題這里有一個(gè)demo代碼:http://runjs.cn/code/wnmdzvwg

既然看源碼沒什么收獲,那么就去網(wǎng)上搜搜文章看看吧。這個(gè)過程中找到一篇很好的文章,這篇文章介紹了

$formatters,$parsers,$render以及$setViewValue。這里就不再介紹了,如果需要學(xué)習(xí),原文在這里:http://blog.csdn.net/qq_17371...

在學(xué)習(xí)$setViewValue時(shí)也發(fā)現(xiàn)一個(gè)很容易被坑的點(diǎn):在調(diào)用$setViewValue時(shí),如果參數(shù)是引用變量,那么如果引用變量地址沒變,則這個(gè)變量被認(rèn)為沒有改變,如 var map = [‘er’, ’tr’];那么map.pop();之后$setViewValue并不認(rèn)為map值改變了。關(guān)于這個(gè)具體可以看我對(duì)這個(gè)問題的回答。順便也附上demo代碼:http://runjs.cn/code/cm7d3pcf
ng-model也有這個(gè)問題,這個(gè)在ng-model源碼注釋中可以看到:

However, custom controls might also pass objects to this method. In
this case, we should make a copy of the object before passing it to
$setViewValue. This is because ngModel does not perform a deep
watch of objects, it only looks for a change of identity.

If you only change the property of the object then ngModel will not
realize that the object has changed and will not invoke the $parsers
and $validators pipelines.

從上面也可以看到其實(shí)一個(gè)變量的更新由view到model和model到view不止$formatters$parsers管道,那么還有哪些呢?

在查了一圈資料后找到一個(gè)很清晰的解釋:https://stackoverflow.com/que...,大家其實(shí)只需要看問題的回答,問題實(shí)在太長(zhǎng)了。。。
這個(gè)回答中有個(gè)demo鏈接,我copy了一下并做了寫小修改放在這個(gè)地址了:http://runjs.cn/code/qte0mm49,這個(gè)demo很清晰的顯示了變量更新的過程,細(xì)節(jié)就不再累述了,這里只把結(jié)果總結(jié)如下:
從model到view:
model值修改 ----> $formatters管道 ----> $render函數(shù) ----> $validators ----> $watch函數(shù)

從view到model:
view值修改 ----> $setViewValue函數(shù)----> $parsers管道 ----> $validators ----> $viewChangeListener函數(shù) ----> $watch函數(shù)
我們也可以直接調(diào)用$setViewValue函數(shù)去直接改變$viewValue 的值,流程會(huì)和上面一樣。
注意在使用$setViewValue時(shí)一定要警惕參數(shù)是引用變量的情況,這個(gè)坑在上文也已經(jīng)提到了。

本文沒有具體介紹$formatters$parsers 管道,關(guān)于這部分可以參考文中給出的鏈接

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

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107586.html

相關(guān)文章

  • MVC MVP MVVM

    摘要:,的事件回調(diào)函數(shù)中調(diào)用的操作方法。以為例調(diào)用關(guān)系模式實(shí)際就是將中的改名為,調(diào)用過程基本一致,最大的改良是間的雙向綁定。和間,有一個(gè)對(duì)象,可以操作修改,使用。 參考:MVC,MVP 和 MVVM 的圖示 - 阮一峰http://www.ruanyifeng.com/blo...Web開發(fā)的MVVM模式http://www.cnblogs.com/dxy198...界面之下:還原真實(shí)的MV...

    wushuiyong 評(píng)論0 收藏0
  • MVC MVP MVVM

    摘要:,的事件回調(diào)函數(shù)中調(diào)用的操作方法。以為例調(diào)用關(guān)系模式實(shí)際就是將中的改名為,調(diào)用過程基本一致,最大的改良是間的雙向綁定。和間,有一個(gè)對(duì)象,可以操作修改,使用。 參考:MVC,MVP 和 MVVM 的圖示 - 阮一峰http://www.ruanyifeng.com/blo...Web開發(fā)的MVVM模式http://www.cnblogs.com/dxy198...界面之下:還原真實(shí)的MV...

    Tangpj 評(píng)論0 收藏0
  • Angular1.x中ngModel$render詳解

    摘要:我們下面來看看的源碼這是其中一個(gè),在不同的指令下的代碼都不太一樣,但是其作用基本一致,但是從這里我們就可以看出的到底在干什么事了。 這篇文章是我兩年前在博客園寫的,現(xiàn)在移植過來,不過Angular 1.x 在國(guó)內(nèi)用的人已經(jīng)不多了,希望能幫助到有需要的人 在我開始著手 ngModel 的領(lǐng)域時(shí)候,有一個(gè)問題很令我糾結(jié),那就是 $render 到底是做什么的呢?查了很多資料都只是簡(jiǎn)單的描述...

    Euphoria 評(píng)論0 收藏0
  • Backbone.js學(xué)習(xí)筆記(一)

    摘要:它通過數(shù)據(jù)模型進(jìn)行鍵值綁定及事件處理,通過模型集合器提供一套豐富的用于枚舉功能,通過視圖來進(jìn)行事件處理及與現(xiàn)有的通過接口進(jìn)行交互。 本人兼職前端付費(fèi)技術(shù)顧問,如需幫助請(qǐng)加本人微信hawx1993或QQ345823102,非誠(chéng)勿擾 1.為初學(xué)前端而不知道怎么做項(xiàng)目的你指導(dǎo) 2.指導(dǎo)并扎實(shí)你的JavaScript基礎(chǔ) 3.幫你準(zhǔn)備面試并提供相關(guān)指導(dǎo)性意見 4.為你的前端之路提供極具建設(shè)性的...

    FrancisSoung 評(píng)論0 收藏0
  • angular2學(xué)習(xí)筆記之基本組件和ngFor

    摘要:的思想非常先進(jìn),摒棄了那種復(fù)雜的構(gòu)建模式,采用了組件化開方的方,那我們一起來看一看,一個(gè)基礎(chǔ)的組件是什么樣子的呢。 angular2的思想非常先進(jìn),摒棄了angular1那種復(fù)雜的構(gòu)建模式,采用了組件化開方的方,那我們一起來看一看,一個(gè)基礎(chǔ)的組件是什么樣子的呢。angular2-demoshowImg(http://static.xiaomo.info/images/angular.p...

    wawor4827 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

Forelax

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<