2

私のプロジェクトでは、現在カスタムフォーム/入力ディレクティブを開発しています。

たとえば、次のディレクティブがあります。

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 ) で宣言し、ディレクティブの input で使用できるようにしながら、「プレゼンテーションを使用したカスタム入力」ディレクティブを実行する正しいアプローチを誰かに教えてもらえますか?

たとえば、「要素ディレクティブの属性がディレクティブ内に「コピー」される」と言う方法はありますか?

別名:

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

私の意見では、これは無駄に冗長です。しかし、本当に別のオプションがあるかどうか自問し始めていますか?

トリックは、テキストフィールドタグからその子(入力)タグに属性/ディレクティブをコピーする前(または後?)のディレクティブリンク機能で行うことができますか?

誰かが私のために道を照らしてくれませんか?

4

1 に答える 1

3

これを試していただけますか:

  • validateディレクティブを書きます。addValidationFunction(fn)これには、 anおよび agetValidationFunction()メソッドを公開するコントローラーがあります。

  • ディレクティブにコントローラーをmyValidation要求させ、この特定のディレクティブの検証ロジックを実装する関数を呼び出します。validatectrl.addValidationFunction(myValidationImplementation)myValidationImplementation

  • 別のディレクティブを記述しvalidateInnerます。validateこれには、オプションでその親からのコントローラーが必要です。ngModelこのディレクティブにはコントローラーも必要です。validateコントローラーが見つかった場合はctrl.getValidationFunction()、関数を呼び出してngModelieに登録します。

    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ディレクティブが他のディレクティブを消去するかどうかはわかりません。もしそうなら、それは一貫した振る舞いではありません。

注 2 :myValidationディレクティブは<xxx my-validation>(camelCase → dash-case に注意) として呼び出されます。上記のコードがタイプミスでない場合、これが<text-field> のように思える理由myValidationです。

于 2013-10-10T09:34:00.850 に答える