wake-up-neo.com

So erstellen Sie eine Direktive mit einer dynamischen Vorlage in AngularJS

Wie kann ich eine Direktive mit einer dynamischen Vorlage erstellen?

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

Dies ist, was ich gerade habe, und das Etikett wird korrekt angezeigt. Ich bin mir jedoch nicht sicher, wie ich zusätzliche HTML-Inhalte an die Vorlage anfügen kann. Oder kombinieren Sie 2 Vorlagen zu 1.

29
teepusink

Hatte ein ähnliches Bedürfnis. $compile erledigt die Arbeit. (Nicht ganz sicher, ob dies "der" Weg ist, um es zu tun, immer noch durch eckig arbeiten)

http://jsbin.com/ebuhuv/7/edit - mein Erkundungstest.

Eine Sache, die ich beachten sollte (in meinem Beispiel), war eine meiner Anforderungen, dass sich die Vorlage basierend auf einem type-Attribut ändert, sobald Sie auf "Speichern" geklickt haben, und die Vorlagen waren sehr unterschiedlich. Sie erhalten jedoch die Datenbindung. Wenn Sie dort eine neue Vorlage benötigen, müssen Sie sie erneut kompilieren.

18
nowk

ich habe den $ templateCache benutzt, um etwas Ähnliches zu erreichen. ich habe mehrere ng-vorlagen in einer einzigen html-datei gespeichert, auf die ich mit der templateUrl der Direktive verweise. Dadurch wird sichergestellt, dass die HTML-Datei für den Vorlagen-Cache verfügbar ist. dann kann ich einfach per id auswählen, um die gewünschte ng-vorlage zu erhalten.

template.html:

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

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

direktive:

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);
        }
    };
}]);
29
zim

Sie sollten Ihren Switch mithilfe der Direktive ' ng-switch ' in die Vorlage verschieben:

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);
        }
    };
});

Es kann so verwendet werden:

<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="[email protected]"></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>
8
Aquajet

Wenn Sie AngularJs Direktive mit dynamischer Vorlage verwenden möchten, können Sie diese Antworten verwenden. Hier sind jedoch mehr professional und legal Syntax davon .Sie können templateUrl nicht nur mit einem einzigen Wert verwenden. Sie können Verwenden Sie es als Funktion, die einen Wert als URL zurückgibt. Diese Funktion verfügt über einige Argumente, die Sie verwenden können.

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

3

Eine Möglichkeit ist die Verwendung einer Vorlagenfunktion in Ihrer Direktive:

...
template: function(tElem, tAttrs){
    return '<div ng-include="' + tAttrs.template + '" />';
}
...
2
user2173353

Ich habe dieses Problem gelöst. Unten ist der Link:

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

mit der spezifischen Datei:

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

Die dynamicTemplate-Direktive hostet eine dynamische Vorlage, die innerhalb des Gültigkeitsbereichs übergeben wird, und gehostete Element verhält sich wie andere native Winkelelemente.

scope.template = '< div ng-controller="SomeUberCtrl">rocks< /div>'
1
nakosung

Ich war in derselben Situation, meine Komplettlösung wurde veröffentlicht hier

Grundsätzlich lade ich auf diese Weise eine Vorlage in die Direktive

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

dann kann ich entsprechend dem Wert von maxLength und required dynamisch eine der 2 Vorlagen laden, wobei nur jeweils eine davon angezeigt wird.

Ich hoffe, es hilft.

0