簡體   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