[英]Is it possible to detect changes to ng-model in a directive without a deep $watch
我正在編寫帶有自定義驗證邏輯的指令來驗證對象。
HTML:
<input type="hidden" name="obj" ng-model="vm.obj" validate-object />
JS:
angular
.module('myApp')
.directive('validateObject', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$validators.validateObject = myValidator;
function myValidator (modelValue, viewValue) {
return validateObject(modelValue);
}
function validateObject (obj) {
// Look inside the object
}
}
}
});
問題在於,當更改對象內部的屬性時,驗證程序不會運行。
我可以添加一個帶有objectEquality === true
的$watch
,然后使用驗證邏輯手動添加$setCustomValidity
。 像這樣:
link: function (scope, element, attrs, ngModelCtrl) {
scope.$watch(attrs.ngModel, onModelChange, true);
function onModelChange (newValue) {
ngModelCtrl.$setCustomValidity('validateObject', validateObject(newValue))
}
function validateObject (obj) {
// Look inside the object
}
}
但是我不喜歡使用老式的手動使用$setValidity
NgModelController
方式,加上添加手動$watch
而NgModelController
已經有在更新過程中注冊的方式(例如$formatters
),此外, $watch
是一個很深的方法可能會有性能問題。
我搞錯了嗎? 有沒有更好的辦法?
從https://github.com/angular/angular.js/blob/master/src/ng/directive/ngModel.js#L699 :
if (ctrl.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !ctrl.$$hasNativeValidators)) {
return;
}
ngModel對模型的較舊版本執行平面相等性檢查,因此對象內部的任何更改都不會反映在ngModel或ngChange上。
推薦的方法是使用不可變數據,這意味着每次更改模型(對象)時,都應創建一個新副本:
function changeModel(){
this.vm.name = "roy";
// Create a new object for ngModel;
this.vm = angular.copy(this.vm);
}
編輯
我記得我以前解決過上一個問題。 您希望具有一組綁定到對象屬性的ng模型,並為整個對象設置1個更改偵聽器。
這是我的解決方案: http : //plnkr.co/edit/6tPMrB8n1agINMo252F2?p=preview
我要做的是創建一個新的指令“ formModel”,該指令必須放在表單元素上。 Angular有一個帶有控制器的form指令。 NgModelController需要一個父表單控制器,然后它將其自身添加到表單中(這是您在整個表單上獲得有效性的方式)。 因此,在我的指令中,我裝飾了表單的$ addControl方法,並為每個通過$ viewChangeListeners添加自身的ngModelController添加了一個偵聽器,現在在表單內ngModel的每次更改時,formModel指令都將復制整個對象並觸發$ setViewViewValue 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.