摘要:我們下面來看看的源碼這是其中一個,在不同的指令下的代碼都不太一樣,但是其作用基本一致,但是從這里我們就可以看出的到底在干什么事了。
這篇文章是我兩年前在博客園寫的,現在移植過來,不過Angular 1.x 在國內用的人已經不多了,希望能幫助到有需要的人
在我開始著手 ngModel 的領域時候,有一個問題很令我糾結,那就是 $render 到底是做什么的呢?查了很多資料都只是簡單的描述一下,這就令我很糾結了,終于在一個陽光明媚的晚上,我終于解決了這個大問題
那么這個 $render 方法到底是干什么的呢?他的用處就是在 $viewValue 改變的時候可以重新綁定 model 數據,但是我們要注意一點( $viewValue 和 DOM 節點的 value 是不同的),我覺得他們的區別有點類似 setTimeout 和 $timeout 的區別,但是又不太一樣。PS:其實 modelValue 和綁定的數據也可以不同
Input里面模型的值:{{vm.modelTest}}
.directive("modelRender", function () { return { require: "ngModel", link: function (scope, iElm, iAttrs, ngModelCtrl) { iElm.on("mouseenter", function () { //嘗試注釋 iElm.val(1); console.log(ngModelCtrl); //嘗試注釋 ngModelCtrl.$setViewValue(11); console.log(ngModelCtrl); //嘗試注釋 ngModelCtrl.$render(); console.log(ngModelCtrl); }) } } } )
我們分幾種情況分析
這是鼠標沒有經過指令的時候的樣子
1.當我們使用 js 原生方法設置 input 的 val 值的時候,并且不執行 $render 函數,我們可以看到 input 里面的 model 值是沒有變化的,但是 input 的的 value 是變成了 1,而且我們看到不僅 model 值沒有變化,ngModel 的 $viewValue 和 $modelValue 同樣也沒有變化。我們可以得出結論 (input 的 value 值不一定等于 $viewValue)
結果是這樣的
然后,我們嘗試在執行 js 原生改變 value 值之后,執行 $render 函數是個什么樣的狀況,
看完上面的實驗之后我們發現 input 的 value 值并沒有發生變化,也就是說 js 原生改變 input 的 value 值是無效的,那么在這里我們就可以看到 $render 的功能了。
我們可以大膽的預計 $render 的功能跟 $apply 的功能是一致的,我們在上一章講過,$apply 是以 viewValue 為主,讓 modelValue 變成 viewValue,也就是 modelValue -> viewValue,那么 $render 是不是以 modelValue 為主,讓 viewValue->modelValue 呢?
2.接下來我們嘗試,使用 ng 原生改變 也就是說 $setviewValue,是如何表現的呢?
現在我們注釋掉 js 原生改變 value 的方法,而去使用 $setViewValue,并且不執行 $render 函數,直接上結果,我們看到,執行完 $setViewValue 之后,無論是 viewValue 和 modelValue 都是已經同步了,但是 input 里面的值卻依然是 test,在這里我們再次驗證了那個說法( $viewValue 和 DOM 節點的 value 是不同的)
現在我們在 $setViewValue 之后使用,$render() 看看是什么效果,
大家發現了吧,$render 的功能和 $apply 的功能極為相似,但是是不是很多人在講 $render 的時候,都會說 model 同步到 view,我覺得這個說法不太對,我測試過在 click 事件用非常規手段改變 controller 中 model 的值,發現就算 controller 的值已經改變了,但是 ngModel 的值無論是 viewValue 還是 modelValue 都沒有變化,然后嘗試用 $modelValue 的屬性強行改變$modelValue,結果還是沒作用。我們下面來看看 $render 的源碼
ctrl.$render = function() { element.val(ctrl.$isEmpty(ctrl.$viewValue) ? "" : ctrl.$viewValue); };
這是其中一個,$render 在不同的指令下的代碼都不太一樣,但是其作用基本一致,但是從這里我們就可以看出 $render 的到底在干什么事了。那么 $render 什么時候觸發呢?其實看你自己想什么時候調用它,你可以覆蓋他的方法,重寫,在 $watch 也好,$viewChange 也好。默認的觸發事件一些特別 input 的 value 改變的時候例如單選,還有 rollbackView()的時候
另外一個真正體現 $render 執行事件的源代碼在這里,里面我寫了注釋,大家應該都能懂,好了,$render 就已經講完了
$scope.$watch(function ngModelWatch() { //解析ngModel的表達式,獲取內容 var modelValue = ngModelGet($scope); // if scope model value and ngModel value are out of sync // TODO(perf): why not move this to the action fn? //判斷表達式的值是否跟modelValue一致 if (modelValue !== ctrl.$modelValue && // checks for NaN is needed to allow setting the model to NaN when there"s an asyncValidator (ctrl.$modelValue === ctrl.$modelValue || modelValue === modelValue) ) { //更新modelValue的值 ctrl.$modelValue = ctrl.$$rawModelValue = modelValue; parserValid = undefined; //獲取管道信息 var formatters = ctrl.$formatters,idx = formatters.length; var viewValue = modelValue; while (idx--) { viewValue = formatters[idx](viewValue); } //如果viewValue和ModelValue不一致 if (ctrl.$viewValue !== viewValue) { ctrl.$viewValue = ctrl.$$lastCommittedViewValue = viewValue; ctrl.$render(); ctrl.$$runValidators(modelValue, viewValue, noop); } } //返回解析的表達式 return modelValue; });
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92914.html
摘要:關于個管道的用法會在下一篇里面講。一般需要通過去調用方法去時和上掛載的屬性值保持一致。方法是可以重新自定義的上的屬性值,已經發生變化利用這些值再次可以再次做相應的處理,然后更新抽時間把關于再補上。參考資料指令中使用中的的詳解 第一個點,要了解下: DOM value $viewValue $modelValue scope上掛載的屬性的值 一般有2個流程: $vie...
摘要:為了簡單起見,在本文中將會使用。已經實例化了并且將它的模板載入到了元素中。中的依賴注入發生在該類的構造函數中,因此我們將在構造函數中注入。 國內 Angular2 資料比較少,這里看到一篇不錯的入門文章就分享過來了 —— Angular 2 快速上手,這里面還有很多有關于 Angular2 的文章,感興趣的朋友可以去看一看 目前angular2已經來到了beta版,這意味著它已經做好了...
摘要:可以在不必打斷其它業務的前提下,升級應用程序,因為這項工作可以多人協作完成,在一段時間內逐漸鋪開,下面就方案展開說明主要依賴提供模塊。在混合式應用中,我們同時運行了兩個版本的。這意味著我們至少需要和各提供一個模塊。 angular1.x 升級 angular2+ 方案 我給大家提供的是angular1.x和angular5并行,增量式升級方案,這樣大家可以循序漸進升級自己的應用,不想看...
摘要:但實際上這時程序并沒有計算手續費。經過排查并查閱文檔之后,發現是的問題。本文沒有具體介紹和管道,關于這部分可以參考文中給出的鏈接 事情起源于在項目中遇到的一個小問題:項目中需要一個輸入框輸入賣出產品數量,并且在用戶輸入后根據輸入數據計算手續費。很自然的我用了ng-model和ng-change,并且一般情況下沒什么問題。問題是:輸入框下還有一個按鈕是全部賣出,點擊這個按鈕程序會自動設置...
摘要:技術棧概述大名,顧名思義是在年月正式發布的一套標準。小名,意為第六次變更。本項目,選擇的是的推薦配置,唯一注意的是全局變量中把的關鍵詞加上。項目結構公共組件目錄,放一些二次封裝的等等片段式的。項目的公用樣式目錄。 技術棧概述 ES2015(ES6) 大名ES2015,顧名思義是 ECMAScript 在2015年6月正式發布的一套標準。小名ES6,意為ECMAScript第六次變更。(...
閱讀 1631·2021-10-27 14:13
閱讀 1868·2021-10-11 10:59
閱讀 3367·2021-09-24 10:26
閱讀 1925·2019-08-30 12:48
閱讀 3041·2019-08-30 12:46
閱讀 2033·2019-08-30 11:16
閱讀 1414·2019-08-30 10:48
閱讀 2740·2019-08-29 16:54