我有以下自定义验证程序指令:
app.directive('validator', ['storeService', function (storeService) {
return {
require: '^ngModel',
link: function ($scope, $element, $attrs, $ctrl) {
$ctrl.$parsers.unshift(function (viewValue) {
var store = storeService.find(viewValue);
if (store == undefined) {
$ctrl.$setValidity('store', false);
return undefined;
} else {
$ctrl.$setValidity('store', true);
return store;
}
});
}
};
}]);
对'storeService.find(viewValue);'的调用检查viewValue是否存在。在进行查找时,它会降低viewValue和商店集中的每个商店的大小。如果它与商店匹配,它将使用正确的套管从服务返回商店。
因此,例如,'london'中的用户类型和服务返回'London'。
如何使用服务中的值更新视图?
答案 0 :(得分:1)
由于你在你的指令中输入了'ngModel',你链接函数中的$ ctrl将是ngModelController。你必须在范围内调用ngController的方法$ setViewValue。$ apply函数而不是调用ngController的$ render方法,如下所示:
else {
$ctrl.$setValidity('store', true);
// sets viewValue
scope.$apply(function(){
$ctrl.$setViewValue($VALUE_YOU_WISH);
});
// renders the input with the new viewValue
$ctrl.$render()
// returns store as parameter for next parser in the pipeline
return store;
}
请记住,您将解析为$ parsers的函数的返回值将作为ngModelControllers $ parsers管道中下一个解析器的参数传递,而不是将在视图中呈现的值。
答案 1 :(得分:0)
我在早期版本的angular中发现,从$setViewValue
函数调用$parsers
会触发Maximum call stack size exceeded
错误,因为setViewValue会触发解析器管道,从而创建一个循环。解决此问题的一种方法是在模型控制器上专门设置$viewValue
属性,然后调用$render()
:
$ctrl.$parsers.unshift(function (viewValue) {
...
// in your parser function
$ctrl.$viewValue = 'your value';
$ctrl.$render();
// no need for $apply, $render will update the DOM
...
}