【问题标题】:How to add arbitrary attributes to an angular directive for data validation如何将任意属性添加到角度指令以进行数据验证
【发布时间】:2014-12-18 10:49:31
【问题描述】:

我正在尝试创建一个角度指令,它将成为我们应用程序中输入字段的自定义标记。本质上,它将创建标签、输入字段和各种引导类,以便它们具有一致的外观。

除此之外,如果我可以添加适合特定输入的各种数据验证器(例如必需和自定义验证器)作为自定义标记的属性,然后将它们添加到输入字段中,我希望它对此进行验证。

我想出了一种方法,似乎将属性放在输入字段上,并且自定义验证器被调用并正确评估数据,但表单似乎从未认为数据无效。我认为我遇到了一个范围问题,其中输入无效是在指令的范围而不是父范围上设置的,但我不是 100% 确定这一点,即使这是我不知道如何解决的问题它。

这是我希望其中一个标签看起来像的示例

<textinput ng-model="TestValue" name="TestValue" text="Label Text" config="GetConfigurationForm()" ngx-ip-address required></textinput>

我想生成类似的东西

<div class="row">
    <div class="form-group" ng-class="{ 'has-error': IsInvalid() }">
        <label for="{{name}}" class="control-label">{{text}}</label>
        <input id="{{name}}" type="text" class="form-control" ng-model="ngModel" name="{{name}}" ngx-ip-address required>
    </div>
</div>

请注意,ngx-ip-address 和 required 已移至输入字段属性。

我的控制器如下所示(抱歉太长了)

var app = angular.module('test', []);

app.directive('ngxIpAddress', function()
{
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attributes, ngModel)
        {
            ngModel.$validators.ngxIpAddress = function(modelValue, viewValue)
            {
                // Value being blank is OK
                if (ngModel.$isEmpty(modelValue))
                    return true;

                // If the string starts with a character then
                // this is not valid
                if (isNaN(parseInt(viewValue[0])))
                    return false;

                var blocks = viewValue.split(".");
                if(blocks.length === 4)
                {
                    return blocks.every(function(block)
                    {
                        return parseInt(block, 10) >= 0 && parseInt(block, 10) <= 255;
                    });
                }

                return false;
            };
        }
    };
});

    app.directive('textinput', function ()
    {
        return {
            restrict: 'E',
            scope: {
                //@ reads the attribute value, = provides two-way binding, & works with functions
                ngModel: '=',
                name: '@',
                text: '@',
                config: '&'
            },
            controller: function($scope) {
                $scope.IsInvalid = function()
                {
                    var getConfigurationFunction = $scope.config();
                    if (!getConfigurationFunction || !getConfigurationFunction[$scope.name])
                        return false;

                    return getConfigurationFunction[$scope.name].$invalid;
                };
            },
            link: function(scope, element, attributes) {
                var inputElement = element.find("input");
                for (var attribute in attributes.$attr)
                {
                    if (attribute !== "ngModel"
                        && attribute !== "name"
                        && attribute !== "text"
                        && attribute !== "config")
                    {
                        inputElement.attr(attribute, attributes[attribute]);
                    }
                }
            },
            template: '<div class="row">' +
                '<div class="form-group" ng-class="{ \'has-error\': IsInvalid() }">' +
                '<label for="{{name}}" class="control-label">{{text}}</label>' +
                '<input id="{{name}}" type="text" class="form-control" ng-model="ngModel" name="{{name}}">' +
                '</div>' +
                '</div>'
        };
    });

    app.controller(
        "TestController",
        [
            "$scope",
            function TestController(_scope)
            {
                _scope.TestValue = "TestTest";
                _scope.GetConfigurationForm = function()
                {
                  return _scope.ConfigurationForm;
                };
            }
        ]
    );

如果我将属性放在实际模板中,那么一切都会按预期工作,如果数据不是 IP 地址,则控件会变为红色。当我通过移动它们添加属性时不起作用。

这是一个 plunkr,显示了我到目前为止所获得的内容:http://plnkr.co/edit/EXkz4jmRif1KY0MdIpiR

这是一个 plunkr,显示了我希望最终结果看起来像我将标签添加到模板而不是标签的位置:http://plnkr.co/edit/mUGPcl1EzlHUiMrwshCr

为了让这更有趣,将来我实际上还需要从外部范围向数据验证指令传递一个值,但我想先让它工作。

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

    Here你可能会找到正确答案。

    这个问题的原因是:

    1. attr会将属性从ngxIpAddress转换为ngxipaddress,即从大写转换为小写,你可以从link找到这个问题。要解决它,只需将ngx-ip-address 作为函数attr 的参数传递。

    2. $compile(inputElement)(scope); 需要添加到指令中,当一个指令用于另一个指令时。这是一个link

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多