淺談Angular中ngModel的$render
在我開(kāi)始著手ngModel的領(lǐng)域時(shí)候,有一個(gè)問(wèn)題很令我糾結(jié),那就是$render()到底是做什么的呢?查了很多資料都只是簡(jiǎn)單的描述一下,這就令我很糾結(jié)了,終于在一個(gè)陽(yáng)光明媚的晚上,我終于解決了這個(gè)大問(wèn)題
那么這個(gè)$render方法到底是干什么的呢?他的用處就是在$viewValue改變的時(shí)候可以重新綁定model數(shù)據(jù),但是我們要注意一點(diǎn)($viewValue和DOM節(jié)點(diǎn)的value是不同的),我覺(jué)得他們的區(qū)別有點(diǎn)類(lèi)似setTimeout和$timeout的區(qū)別,但是又不太一樣。ps:其實(shí)modelValue和綁定的數(shù)據(jù)也可以不同
Input里面模型的值:{{vm.modelTest}}
<input type="text" ng-model="vm.modelTest" model-render>
.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);
})
}
}
})
我們分幾種情況分析
這是鼠標(biāo)沒(méi)有經(jīng)過(guò)指令的時(shí)候的樣子

1.當(dāng)我們使用js原生方法設(shè)置input的val值的時(shí)候,并且不執(zhí)行$render函數(shù),我們可以看到input里面的model值是沒(méi)有變化的,但是input的的value是變成了1,而且我們看到不僅model值沒(méi)有變化,ngModel的$viewValue和$modelValue同樣也沒(méi)有變化。我們可以得出結(jié)論 (input的value值不一定等于$viewValue)
結(jié)果是這樣的

--------------------------------------------------------------------------
然后,我們嘗試在執(zhí)行js原生改變value值之后,執(zhí)行$render函數(shù)是個(gè)什么樣的狀況,

看完上面的實(shí)驗(yàn)之后我們發(fā)現(xiàn)input的value值并沒(méi)有發(fā)生變化,也就是說(shuō)js原生改變input的value值是無(wú)效的,那么在這里我們就可以看到$render的功能了。
我們可以大膽的預(yù)計(jì)$render的功能跟$apply的功能是一致的,我們?cè)谏弦徽轮v過(guò),$apply是以viewValue為主,讓modelValue變成viewValue,也就是modelValue -> viewValue,那么$render是不是以modelValue為主,讓viewValue->modelValue呢?
-------------------------------------------------------------------------------------------------
2.接下來(lái)我們嘗試,使用ng原生改變 也就是說(shuō)$setviewValue,是如何表現(xiàn)的呢?
現(xiàn)在我們注釋掉js原生改變value的方法,而去使用$setViewValue,并且不執(zhí)行$render函數(shù),直接上結(jié)果,我們看到,執(zhí)行完$setViewValue之后,無(wú)論是viewValue和modelValue都是已經(jīng)同步了,但是input里面的值卻依然是test,在這里我們?cè)俅悟?yàn)證了那個(gè)說(shuō)法($viewValue和DOM節(jié)點(diǎn)的value是不同的)

現(xiàn)在我們?cè)?setViewValue之后使用,$render()看看是什么效果,

大家發(fā)現(xiàn)了吧,$render的功能和$apply的功能極為相似,但是是不是很多人在講$render的時(shí)候,都會(huì)說(shuō)model同步到view,我覺(jué)得這個(gè)說(shuō)法不太對(duì),我測(cè)試過(guò)在click事件用非常規(guī)手段改變controller中model的值,發(fā)現(xiàn)就算controller的值已經(jīng)改變了,但是ngModel的值無(wú)論是viewValue還是modelValue都沒(méi)有變化,然后嘗試用$modelValue的屬性強(qiáng)行改變$modelValue,結(jié)果還是沒(méi)作用。
我們下面來(lái)看看$render的源碼
ctrl.$render = function() {
element.val(ctrl.$isEmpty(ctrl.$viewValue) ? '' : ctrl.$viewValue);
};
這是其中一個(gè),$render在不同的指令下的代碼都不太一樣,但是其作用基本一致,但是從這里我們就可以看出$render的到底在干什么事了。那么$render什么時(shí)候觸發(fā)呢?其實(shí)看你自己想什么時(shí)候調(diào)用它,你可以覆蓋他的方法,重寫(xiě),在$watch也好,$viewChange也好。默認(rèn)的觸發(fā)事件一些特別input的value改變的時(shí)候例如單選,還有rollbackView()的時(shí)候
另外一個(gè)真正體現(xiàn)$render執(zhí)行事件的源代碼在這里,里面我寫(xiě)了注釋?zhuān)蠹覒?yīng)該都能懂
$scope.$watch(function ngModelWatch() {
//解析ngModel的表達(dá)式,獲取內(nèi)容
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?
//判斷表達(dá)式的值是否跟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);
}
}
//返回解析的表達(dá)式
return modelValue;
});
}];
以上就是小編為大家?guī)?lái)的淺談Angular中ngModel的$render全部?jī)?nèi)容了,希望大家多多支持腳本之家~
相關(guān)文章
AngularJs實(shí)現(xiàn)分頁(yè)功能不帶省略號(hào)的代碼
這篇文章主要介紹了AngularJs實(shí)現(xiàn)分頁(yè)功能不帶省略號(hào)的代碼的相關(guān)資料,非常不錯(cuò)具有參考借鑒價(jià)值,感興趣的朋友一起看看吧2016-05-05
詳解angular2封裝material2對(duì)話(huà)框組件
本篇文章主要介紹了詳解angular2封裝material2對(duì)話(huà)框組件,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-03-03
解決angularjs中同步執(zhí)行http請(qǐng)求的方法
今天小編就為大家分享一篇解決angularjs中同步執(zhí)行http請(qǐng)求的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
AngularJS實(shí)現(xiàn)表單驗(yàn)證功能
這篇文章主要為大家詳細(xì)介紹了AngularJS實(shí)現(xiàn)表單驗(yàn)證功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-01-01
通過(guò)AngularJS實(shí)現(xiàn)圖片上傳及縮略圖展示示例
本篇文章主要介紹了通過(guò)AngularJS實(shí)現(xiàn)圖片上傳及縮略圖展示,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01
angular route中使用resolve在uglify壓縮后問(wèn)題解決
這篇文章主要介紹了angular route中使用resolve在uglify壓縮后問(wèn)題解決的相關(guān)資料,需要的朋友可以參考下2016-09-09

