3

我有以下自定义验证器指令:

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”。

如何使用服务中的值更新视图?

4

2 回答 2

1

由于您在指令中放置了 required:'^ngModel',因此链接函数中的 $ctrl 将是 ngModelController。您必须在 scope.$apply 函数内调用 ngController 的 $setViewValue 方法,然后调用 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 管道中的下一个解析器,而不是将在视图中呈现的值。

于 2013-09-26T21:44:11.720 回答
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
  ...
}
于 2016-02-04T19:16:30.353 回答