繁体   English   中英

Angular:在元素指令上添加属性指令

[英]Angular : Adding Attribute directive on Element Directive

对于我的项目,我目前正在开发自定义表单/输入指令。

例如,我有以下指令:

angular.module('myApp').directive("textField", function() {
    return {
        restrict: 'E',
        replace: true,
        templateUrl : "/common/tpl/form/text-field.html",
        scope : {
            label   : "@",
            model   : "="
        }
    };
});

与相关的模板:

<div class="form-group">
    <label for="{{fieldId}}" class="col-lg-2 control-label">{{label |translate}}</label>
    <div class="col-lg-10">
        <input type="text" class="form-control" id="{{fieldId}}" ng-model="model" placeholder="{{label|translate}}">
    </div>
</div>

我还有更多自定义字段(日期,选择,双选等)。

用法很简单:

<text-field label="app.myLabel" model="myObj.myAttribute"></text-field>

这个想法是通过避免在每个字段上冗长地添加标签来清理主模板。 我相信非常普遍的需要。

现在的问题是:

现在,我需要向输入模型添加自定义验证。

我做过一个幼稚的方法,即创建一个验证指令:

directive('myValidation', function (){
    return {
        require: 'ngModel',
        link: function(scope, elem, attr, ngModel) {
            ngModel.$parsers.unshift(function (value) {
                // do some validation
                return value;
            });
        }
    };
});

然后像这样使用它:

<text-field label="app.myLabel" model="myObj.myAttribute" myValidation="validationOptions"></text-field>

但是当然这是行不通的,很简单,因为replace = true的text-field指令会“擦除”其元素上的验证指令。

有人可以告诉一个做“自定义输入和演示”指令,同时允许验证部分在指令(这里是text-field)上声明并在指令的输入上使用的正确方法是什么?

例如,有没有办法说“我的element指令的属性将被“复制”到我的指令内部?”

又名:

<text-field label="app.myLabel" model="myObj.myAttribute" **myValidation="validationOptions"**></text-field>

将导致:

<div class="form-group">
        <label for="{{fieldId}}" class="col-lg-2 control-label">{{label |translate}}</label>
        <div class="col-lg-10">
            <input type="text" class="form-control" id="{{fieldId}}" ng-model="model" **myValidation="validationOptions"** placeholder="{{label|translate}}">
        </div>
    </div>

还是我只是想念一些东西?

我想避免使用包含来解决此问题,因为这将迫使表单模板看起来像这样:

<field label="myLabel">
     <input type="text" class="form-control" id="{{fieldId}}" ng-model="model" placeholder= {{label|translate}}">    
</field>

在我看来,这只是毫无用处的冗长。 但是我开始问自己,是否真的还有另一种选择?

也许可以在pre(或post?)directve链接函数中完成此技巧,在该函数中,我会将text / field标签中的attribute /指令复制到它的child(输入)标签中?

有人可以为我在那里开路吗?

您可以尝试一下:

  • 编写validate指令。 这将具有一个控制器,该控制器公开一个addValidationFunction(fn)getValidationFunction()方法。

  • myValidation指令需要validate控制器并调用ctrl.addValidationFunction(myValidationImplementation) ,其中myValidationImplementation是为该特定指令实现验证逻辑的函数。

  • 编写另一个指令validateInner 这将需要其父级的validate控制器。 该指令还将需要ngModel控制器。 如果它发现该validate控制器,它调用ctrl.getValidationFunction()并注册与所述功能ngModel即:

     require: ["^?validate", "ngModel"], link: function(scope,el,attrs,ctrls) { if( ctrls[0] != null ) { var validationFn = ctrls[0].getValidationFunction(); // register validationFn with ngModel = ctrls[1] } ... } 
  • 在您的textField模板中:

     <input validate-inner type="text" class="form-control" id="{{fieldId}}" ng-model="model" placeholder="{{label|translate}}"> 

用法:

<text-field label="app.myLabel" model="myObj.myAttribute"
    validate my-validation="validationOptions"></text-field>

注意1 :我不确定replace:true指令是否擦除其他指令。 如果是这样,那就不是一致的行为。

注意2myValidation指令被称为<xxx my-validation> (注意camelCase→破折号)。 如果上面的代码不是拼写错误,那么这就是为什么<text-field >似乎擦除myValidation

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM