无法使用指令隔离范围绑定角度验证错误

时间:2014-12-19 08:35:08

标签: angularjs directive

我的总体目标是将所有可重用的小部件组件化为角度指令,但在尝试制作角度形式错误消息指令时却很困难。我已阅读了很多帖子,但无法看到如何实现这一目标。

我的所有指令都有隔离范围。

我的主要问题是我不知道如何使pattern属性正确绑定到at-error-message指令span元素的ng-show属性,以便错误消息根据模式动态隐藏\ shows

外部HTML是:

<body ng-controller="atVrmLookup">
    <ng-form name="vrmForm" novalidate>
    <at-input name="registration" label="Registration" required model="vrmLookup.registration" minlength="3"></at-input>
    <at-error-message pattern="vrmForm.registration.$error.required" message="Please enter a registration"></at-error-message>
    </ng-form>
</body>

atInput指令是

uiComponents.directive('atInput', function () {
    return {
        // use an inline template for increased
        template: '<div><label>{{label}}</label><div><input name="{{name}}" type="text" ng-model="model" ng-minlength="{{minlength}}"/></div></div>',
        // restrict directive matching to elements
        restrict: 'E',
        scope: {
            name: '@',
            label: '@',
            minlength: '@',
            model:'=model'
        },
        compile: function (element, attr, scope) {
            var input = element.find('input');

            if (!_.isUndefined(attr.required)) {
                input.attr("required", "true");
            }

        },
        controller: function ($scope, $element, $attrs) {
            // declare some default values
        }
    };

});

atErrorMessageDirective是

uiComponents.directive('atErrorMessage', function () {
    return {
        // use an inline template for increased
        template: '<span class="error" ng-show="pattern">{{message}}</span>',
        // restrict directive matching to elements
        restrict: 'E',
        scope: {
            message: '@',
            pattern: '='
        },
        controller: function ($scope, $element, $attrs) {
            // declare some default values
        }

    };
});

以下是了解问题的傻瓜。

http://plnkr.co/edit/5tdsqSXg0y5bfQqJARFB

任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

输入名称不能是有角度的绑定表达式。而是使用模板函数,并构建模板字符串:

template: function($element, $attr) {
   return '<div><label>{{label}}</label><div>' + 
        '<input name="' + $attr.name + '" type="text" ng-model="model" ng-minlength="{{minlength}}"/>' + 
          '</div></div>';
}

替代解决方案

实现dynamic-name指令,并使用angular form指令公开的API以编程方式设置ngModel的名称,并将ngModel控件添加到表单中:

.directive("dynamicName",[function(){
    return {
        restrict:"A",
        require: ['ngModel', '^form'],
        link:function(scope,element,attrs,ctrls){
            ctrls[0].$name = scope.$eval(attrs.dynamicName) || attrs.dynamicName;
            ctrls[1].$addControl(ctrls[0]);
        }
    };
}])

然后在你的模板中:

    template: '<div><label>{{label}}</label><div><input dynamic-name="{{name}}" type="text" ng-model="model" ng-minlength="{{minlength}}"/></div></div>',

注意:此解决方案有效,因为幸运的是,ngForm提供了编程访问来自定义其行为。如果ngForm的控制器没有公开API,那么你可能已经是SOL了。考虑从您自己的自定义指令控制器公开的API,这是一种很好的做法 - 您永远不会知道其他指令如何使用它。