[英]Can I prevent an ng-model update with an asyncValidator?
我有一個應用程序,其中某些選項不能很好地配合使用。 如果用戶選擇了一對可能導致性能不佳的選項,我們將顯示一個對話框 ,其中用戶必須同意承認他們正在請求大量數據,而我們可能無法滿足請求。
由於對話框服務返回的承諾可以根據用戶的意願執行或拒絕,因此在NgModelController上添加異步驗證器似乎是一個不錯的地方。 我寫了一個小插曲,以演示這種情況和我對解決方案的嘗試。
它的膽量是:
<body ng-controller="MainCtrl as ctrl">
<br>
Allow chili
<input type="checkbox" ng-model="ctrl.allowChili">
<br>
<select
ng-model="ctrl.val"
ng-model-options="{allowInvalid: false}"
validate-async="ctrl.validateAsync($modelVal)"
ng-change="ctrl.tellMe()">
<option value="very">very</option>
<option value="chili">chili</option>
<option value="jalepeno">jalepeno</option>
</select>
<br>
<p>The food is {{ctrl.val}} spicy!</p>
</body>
var myApp = angular.module('plunker', []);
myApp.controller('MainCtrl', ['$q', '$scope', function($q, $scope) {
this.val = 'very';
this.allowChili = false;
this.validateAsync = function(modelVal) {
console.log(modelVal);
if (modelVal != 'chili' || this.allowChili) {
console.log('Accepting validation');
return $q.when();
} else {
console.log('Rejecting validation');
return $q.reject();
}
};
this.tellMe = function() {
// In my application, this actually issues an HTTP request to get new
// data and update the view.
alert('model value changed');
};
}]);
myApp.directive('validateAsync', ['$q', function($q) {
return {
restrict: 'A',
require: 'ngModel',
link: linkFn,
};
function linkFn(scope, element, attrs, ngModelCtrl) {
ngModelCtrl.$asyncValidators.myValidator = function(modelVal, viewVal) {
var args = {
'$modelVal': modelVal,
'$viewVal': viewVal,
};
return $q.when(scope.$eval(attrs['validateAsync'], args));
};
}
}]);
不幸的是,有一些問題。 當異步驗證器承諾被拒絕時,會發生兩件事:
ng-change
)仍然會觸發,並且我的視圖仍會更新。 undefined
而我想完全阻止它的更改。 NgModelController
如何防止基於承諾狀態進行階段性更改?
這是一個丑陋的駭客 ,我認為我可以適應我的用例。 更改的內容在validateAsync
指令中:
myApp.directive('validateAsync', ['$q', function($q) {
return {
restrict: 'A',
require: 'ngModel',
link: linkFn,
};
function linkFn(scope, element, attrs, ngModelCtrl) {
var ngModelCtrl$setViewValue = ngModelCtrl.$setViewValue;
ngModelCtrl.$setViewValue = function(value, trigger) {
var args = {
'$val': value,
'$trigger': trigger,
};
$q.when(scope.$eval(attrs['validateAsync'], args)).then(function() {
ngModelCtrl$setViewValue.call(ngModelCtrl, value, trigger);
});
};
}
}]);
(將模板更改為使用$val
而不是$modelVal
)。
基本上,我要劫持NgModelController.$setViewValue
並且如果承諾被拒絕,則不會調用基本實現。 在演示插件中,您將看到select
元素仍然更改。 我認為這對我的設計師來說是可以的(如果不是,我可以在用例中對其進行修復,因為我實際上並未使用<select>
元素-我使用的是自定義指令來選擇我完全控制何時更新的值)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.