4

ディレクティブ宣言で ng-options の使用を維持しながら、カスタム ディレクティブで選択をカプセル化しようとしています。

目標は、my ディレクティブを使用してテンプレート内の ng-options の構文を保持できるようにすることですが、それをディレクティブ内の select の ng-options に正しく転送することです。

以上の言葉、コード:

ディレクティブ:

    angular.module('myApp').directive("selectField", function() {
    return {
        restrict: 'EA',
        replace: true,
        transclude : false,
        templateUrl : "/common/tpl/form/select-field.html",
        scope : {
            label   : "@",
            model   : "=",
            options : "&"
        }
    };
});

テンプレート:

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

使用法:

 <select-field label="myLabel" model="data.mySelectValue" options="p.nom for p in myOptions"></select-field>

そして...エラー:

Error: [$parse:syntax] Syntax Error: Token 'for' is an unexpected token at column 7 of the expression [p.nom for p in preteurs] starting at [for p in preteurs].

オプションを "&" 、 "=" および "@" 属性として試しましたが、何も機能していないようです。

「=」と「&」を使用すると、角度が指定されたエラーで爆発し、「@」属性を使用すると、式はディレクティブ スコープで評価されます。これは機能しますが、「myOptions」がディレクティブ自体のスコープに存在しないため、オプションをレンダリングしません。 ..

何か不足していますか?これを行う方法はありますか?

4

3 に答える 3

1

リストと式を別々の属性として選択する方法は他にありません... http://blog.benkuhl.com/2013/08/how-to-use-ng-options-in-a-custom-directive-ドロップダウン用/

于 2013-09-27T17:49:34.310 に答える
1

私の解決策は、 angular ng-bind-htmlで受け入れられた回答とその中のディレクティブで見つかった驚くべきコンパイル ディレクティブに依存しています... VKammerrer に感謝します。少しお粗末ですが、あなたが投稿したばかりのブログ記事を見ると、それは必要悪かもしれないと思います。

セットアップは次のとおりです。

<select-field compile>

もちろん、select-field とコンパイルを組み合わせて 1 つのディレクティブにすることもできます。

MyCtrl には、スコープで次のように定義されています。

$scope.myOptions = [
    { value: 0, nom: 'a' },
    { value: 1, nom: 'b' }
];

MyView には次の HTML があります。

<select-field options="myOptions" data="nom" compile></select-field>

selectField の宣言は次のとおりです。

angular.module('myApp')
    .directive('selectField',
        function() {
            return {
                restrict: 'E',
                replace: true,
                transclude: false,
                templateUrl: 'scripts/directives/selectField.tmp.html',
                scope: {
                    options: '=',
                    data: '@'
                }
            };
        }
    );

selectField.tmp.html は次のとおりです。

<div>
    <select ng-model="something" ng-options="p.{{data}} for p in options"></select>
</div>

わかりました、それは私にとってはうまくいくようです。それが役立つ/うまくいかない場合はお知らせください。

于 2013-09-27T18:07:33.623 に答える
1

コンパイルを伴わない代替手段を見つけました。

カスタム ディレクティブでは、2 つのバインディングを定義します。

selectOptions: "<", // One way, it will contain the source array
selectOptionsExp: "@" // Literal string, it will contain the options expression

次に、テンプレートでこの html を使用できます。

<select ng-model="..." ng-options="{{ vm.selectOptionsExp }}"></select>

そして、これは使用法です:

<my-directive ng-model="vm.selectedValue"
              select-options="vm.valuesArray"
              select-options-exp="item.label for item in vm.selectOptions track by item.id" />

「vm.selectOptions」は内部スコープで渡されるため、コンパイルやトランスクルードに頼らずに利用できることに注意してください。

さらに、変数が現在のスコープに存在しないことをリーダーに明確にする、置き換え可能なトークンを使用して使用法を簡素化できます。

vm.getOptionsExp = function() { return vm.selectOptionsExp.replace("$options", "vm.selectOptions"); }
<select ng-model="..." ng-options="{{ vm.getOptionsExp() }}"></select>
<my-directive ng-model="vm.selectedValue"
                  select-options="vm.valuesArray"
                  select-options-exp="item.label for item in $options track by item.id" />

これは、個別のオプションを使用してカスタム関数の並べ替え/フィルタリングを含めるように拡張できます。

于 2017-10-10T10:27:02.957 に答える