29

動的テンプレートを使用してディレクティブを作成するにはどうすればよいですか?

'use strict';

app.directive('ngFormField', function($compile) {
return {
    transclude: true,
    scope: {
        label: '@'
    },
    template: '<label for="user_email">{{label}}</label>',
    // append
    replace: true,
    // attribute restriction
    restrict: 'E',
    // linking method
    link: function($scope, element, attrs) {
        switch (attrs['type']) {
            case "text":
                // append input field to "template"
            case "select":
                // append select dropdown to "template"
        }
    }
  }
});
<ng-form-field label="First Name" type="text"></ng-form-field>

これは私が今持っているものであり、ラベルを正しく表示しています。ただし、テンプレートにHTMLを追加する方法がわかりません。または、2つのテンプレートを1つに組み合わせます。

4

7 に答える 7

32

$ templateCacheを使用して、同様のことを実行しました。ディレクティブのtemplateUrlを使用して参照する単一のhtmlファイルに複数のng-templateを配置します。これにより、HTMLがテンプレートキャッシュで利用できるようになります。次に、idで選択するだけで、必要なng-templateを取得できます。

template.html:

<script type="text/ng-template" id=“foo”&gt;
foo
</script>

<script type="text/ng-template" id=“bar”&gt;
bar
</script>

指令:

myapp.directive(‘foobardirective’, ['$compile', '$templateCache', function ($compile, $templateCache) {

    var getTemplate = function(data) {
        // use data to determine which template to use
        var templateid = 'foo';
        var template = $templateCache.get(templateid);
        return template;
    }

    return {
        templateUrl: 'views/partials/template.html',
        scope: {data: '='},
        restrict: 'E',
        link: function(scope, element) {
            var template = getTemplate(scope.data);

            element.html(template);
            $compile(element.contents())(scope);
        }
    };
}]);
于 2014-01-15T17:24:51.117 に答える
17

同様のニーズがありました。$compile仕事をします。(これが「THE」の方法であるかどうかは完全にはわかりませんが、Angularを介して作業を続けています)

http://jsbin.com/ebuhuv/7/edit-私の探索テスト。

type注意すべき点の1つ(私の例による)、私の要件の1つは、[保存]をクリックすると、属性に基づいてテンプレートが変更され、テンプレートが大きく異なることでした。したがって、データバインディングを取得しますが、そこに新しいテンプレートが必要な場合は、再コンパイルする必要があります。

于 2013-02-13T20:42:47.797 に答える
8

' ng-switch 'ディレクティブを使用して、スイッチをテンプレートに移動する必要があります。

module.directive('testForm', function() {
    return {
        restrict: 'E',
        controllerAs: 'form',
        controller: function ($scope) {
            console.log("Form controller initialization");
            var self = this;
            this.fields = {};
            this.addField = function(field) {
                console.log("New field: ", field);
                self.fields[field.name] = field;
            };
        }
    }
});

module.directive('formField', function () {
    return {
        require: "^testForm",
        template:
            '<div ng-switch="field.fieldType">' +
            '    <span>{{title}}:</span>' +
            '    <input' +
            '        ng-switch-when="text"' +
            '        name="{{field.name}}"' +
            '        type="text"' +
            '        ng-model="field.value"' +
            '    />' +
            '    <select' +
            '        ng-switch-when="select"' +
            '        name="{{field.name}}"' +
            '        ng-model="field.value"' +
            '        ng-options="option for option in options">' +
            '        <option value=""></option>' +
            '    </select>' +
            '</div>',
        restrict: 'E',
        replace: true,
        scope: {
            fieldType: "@",
            title: "@",
            name: "@",
            value: "@",
            options: "=",
        },
        link: function($scope, $element, $attrs, form) {
            $scope.field = $scope;
            form.addField($scope);
        }
    };
});

次のように使用できます。

<test-form>
    <div>
        User '{{!form.fields.email.value}}' will be a {{!form.fields.role.value}}
    </div>
    <form-field title="Email" name="email" field-type="text" value="me@example.com"></form-field>
    <form-field title="Role" name="role" field-type="select" options="['Cook', 'Eater']"></form-field>
    <form-field title="Sex" name="sex" field-type="select" options="['Awesome', 'So-so', 'awful']"></form-field>
</test-form>
于 2014-07-31T20:51:50.867 に答える
4

1つの方法は、ディレクティブでテンプレート関数を使用することです。

...
template: function(tElem, tAttrs){
    return '<div ng-include="' + tAttrs.template + '" />';
}
...
于 2016-12-19T09:18:58.970 に答える
3

動的テンプレートでAngularJsディレクティブを使用する場合は、それらの回答を使用できますが、ここでは、より専門的合法的な構文を使用します。templateUrlは、単一の値だけでなく、値をurlとして返す関数として使用できます。この関数には、使用できる引数がいくつかあります。

http://www.w3docs.com/snippets/angularjs/dynamically-change-template-url-in-angularjs-directives.html

于 2015-07-22T16:21:34.213 に答える
1

私はなんとかこの問題に対処することができました。以下はリンクです:

https://github.com/nakosung/ng-dynamic-template-example

特定のファイルは次のとおりです。

https://github.com/nakosung/ng-dynamic-template-example/blob/master/src/main.coffee

dynamicTemplateディレクティブは、スコープ内で渡される動的テンプレートをホストし、ホストされる要素は他のネイティブの角度要素のように機能します。

scope.template = '< div ng-controller="SomeUberCtrl">rocks< /div>'
于 2014-02-26T12:57:12.197 に答える
0

私は同じ状況にありました、私の完全な解決策はここに投稿されました

基本的に、この方法でディレクティブにテンプレートをロードします

var tpl = '' + 
    <div ng-if="maxLength" 
        ng-include="\'length.tpl.html\'">
    </div>' +
    '<div ng-if="required" 
        ng-include="\'required.tpl.html\'">
    </div>';

次に、の値に従ってmaxLengthrequired2つのテンプレートの1つを動的にロードできます。必要に応じて、一度に1つだけが表示されます。

私はそれが役立つことを願っています。

于 2015-11-18T04:21:28.877 に答える