通过摘要运行验证指令

时间:2015-01-25 15:09:49

标签: javascript angularjs angularjs-directive

该指令用于确定,如果给定的值是,或者不是与之关联的数据列表。当我键入到输入中时,它可以正常工作,但如果由于 $ digest 循环(为其添加值),数据列表会发生变化,则无法正常工作。如果我更新输入,它将正确

app.directive('list', function (){
    return {
        restrict: "A",
        require: "ngModel",
        priority: 100,
        link: function(scope, elem, attr, ngModel){
            var list;

            //For DOM -> model validation
            ngModel.$validators.list = function(value){
                if(!list){
                    var options = document.getElementById(attr.list).options;
                    var list = [];
                    for(var i=options.length-1; i>=0; i--){
                        if(isString(options[i].getAttribute("valid"))){
                            if(options[i].label){list.push(options[i].label.toLowerCase())}
                            if(options[i].value){list.push(options[i].value.toLowerCase())}
                        }
                    };
                }
                var valid = (value||!value==""?list.indexOf(value.toLowerCase()) !== -1:true);
                return (!list.length)||valid;
            };
        }
    };
});

2 个答案:

答案 0 :(得分:0)

您需要查看列表,然后触发ngModel.$validate();,然后运行验证管道......

app.directive('list', function (){
    return {
        restrict: "A",
        require: "ngModel",
        priority: 100,
        link: function(scope, elem, attr, ngModel){
            var list;


        scope.$watch(function () {
            return $parse(attrs.list)(scope);
        }, function () {
            ngModel.$validate();
        });


            //For DOM -> model validation
            ngModel.$validators.list = function(value){
                if(!list){
                    var options = document.getElementById(attr.list).options;
                    var list = [];
                    for(var i=options.length-1; i>=0; i--){
                        if(isString(options[i].getAttribute("valid"))){
                            if(options[i].label){list.push(options[i].label.toLowerCase())}
                            if(options[i].value){list.push(options[i].value.toLowerCase())}
                        }
                    };
                }
                var valid = (value||!value==""?list.indexOf(value.toLowerCase()) !== -1:true);
                return (!list.length)||valid;
            };
        }
    };
});

答案 1 :(得分:0)

你真的需要阅读这篇SO question关于如何“思考Angular”的内容。

某处你有一个<datalist>,你的id通过list属性传递给你的指令。我想这跟你所拥有的很接近:

<datalist id="myDatalist">
  <options ng-repeat="item in items" value="{{item.value}}">{{item.label}}</options>
</datalist>

<input ng-model="foo" list="myDatalist">

不要尝试从<options>元素或DOM中的任何其他位置“提取”值。您已经拥有$scope.items(或者您将其命名) - 使用它将其传递给您的list指令:

.directive("list", function(){
  return {
    // other directive properties,
    scope: {
       list: "="
    },
    require: "ngModel",
    link: function(scope, element, attrs, ngModel){
       scope.$watchCollection("list", function(){
          ngModel.$validate();
          // do whatever else you need in response to a change in list
       });
       // register validators, etc...
    }
  }
});

然后该指令的用法如下:

<input ng-model="foo" list="items">

这不仅会使用Angular来监视底层数据的变化,还会将您的逻辑与DOM分离,因此如果您决定稍后更改ID,或使用不带<option>的其他元素,那么你的指令不会改变。