亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

angular1學習筆記,view model 的同步過程

Forelax / 1000人閱讀

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

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

  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)聽。所以當我們直接在js中修改ng-model的變量時并不會觸發(fā)ng-change。
問題找到了,解決方案也不難,放棄ng-change,改用$watch就行了。
但是就這么結束了嗎?一個變量從view變化開始到同步更新到model到底經歷了什么呢?反過來呢,是一樣的嗎?
所以我又去看了看ng-model的源碼,并沒有什么收獲,不過意外的了解到了這么個點:
ng-change是在model值變化之前執(zhí)行的。ng-model源碼中有這么個函數(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之后,因為ng-change中很可能會把變量的值又修改回去,這樣變量值事實上就并沒改變(寫api真的是什么情況都要考慮到啊?。。?。關于這一點,以及前面的問題這里有一個demo代碼:http://runjs.cn/code/wnmdzvwg

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

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

在學習$setViewValue時也發(fā)現(xiàn)一個很容易被坑的點:在調用$setViewValue時,如果參數(shù)是引用變量,那么如果引用變量地址沒變,則這個變量被認為沒有改變,如 var map = [‘er’, ’tr’];那么map.pop();之后$setViewValue并不認為map值改變了。關于這個具體可以看我對這個問題的回答。順便也附上demo代碼:http://runjs.cn/code/cm7d3pcf
ng-model也有這個問題,這個在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.

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

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

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

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

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

轉載請注明本文地址:http://www.ezyhdfw.cn/yun/107586.html

相關文章

  • MVC MVP MVVM

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

    wushuiyong 評論0 收藏0
  • MVC MVP MVVM

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

    Tangpj 評論0 收藏0
  • Angular1.x中ngModel$render詳解

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

    Euphoria 評論0 收藏0
  • Backbone.js學習筆記(一)

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

    FrancisSoung 評論0 收藏0
  • angular2學習筆記之基本組件和ngFor

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

    wawor4827 評論0 收藏0

發(fā)表評論

0條評論

Forelax

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<