Comment créer une directive avec un modèle dynamique?
'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>
C’est ce que j’ai pour l’instant et elle affiche correctement l’étiquette. Cependant, je ne sais pas comment ajouter du code HTML supplémentaire au modèle. Ou en combinant 2 modèles en 1.
Avait un besoin similaire. $compile
fait le travail. (Pas tout à fait sûr que ce soit "LA" façon de le faire, travaillant toujours mon chemin angulaire)
http://jsbin.com/ebuhuv/7/edit - mon test d'exploration.
Une chose à noter (d'après mon exemple), une de mes exigences était que le modèle change en fonction d'un attribut type
une fois que vous avez cliqué sur Enregistrer, et que les modèles étaient très différents. Donc, vous obtenez la liaison de données. Si vous avez besoin d’un nouveau modèle, vous devrez le recompiler.
j'ai utilisé le $ templateCache pour accomplir quelque chose de similaire. Je mets plusieurs ng-templates dans un seul fichier html, que je référence en utilisant templateUrl de la directive. qui garantit que le code HTML est disponible pour le cache de modèles. alors je peux simplement sélectionner par id pour obtenir le ng-template que je veux.
template.html:
<script type="text/ng-template" id=“foo”>
foo
</script>
<script type="text/ng-template" id=“bar”>
bar
</script>
directif:
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);
}
};
}]);
Vous devez déplacer votre commutateur dans le modèle en utilisant la directive ' 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);
}
};
});
Il peut être utilisé comme ceci:
<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>
Si vous souhaitez utiliser la directive AngularJs avec un modèle dynamique, vous pouvez utiliser ces réponses. Cependant, les syntaxes professional et legal sont plus nombreuses .Vous pouvez utiliser templateUrl non seulement avec une valeur unique.Vous pouvez utilisez-le en tant que fonction, qui renvoie une valeur sous la forme url. Cette fonction possède des arguments que vous pouvez utiliser.
Une méthode consiste à utiliser une fonction de modèle dans votre directive:
...
template: function(tElem, tAttrs){
return '<div ng-include="' + tAttrs.template + '" />';
}
...
J'ai réussi à gérer ce problème. Ci-dessous le lien:
https://github.com/nakosung/ng-dynamic-template-example
avec le fichier spécifique étant:
https://github.com/nakosung/ng-dynamic-template-example/blob/master/src/main.coffee
La directive dynamicTemplate
héberge un modèle dynamique qui est passé dans scope et l'élément hébergé agit comme d'autres éléments angulaires natifs.
scope.template = '< div ng-controller="SomeUberCtrl">rocks< /div>'
Je suis dans la même situation, ma solution complète a été postée ici
Fondamentalement, je charge un modèle dans la directive de cette manière
var tpl = '' +
<div ng-if="maxLength"
ng-include="\'length.tpl.html\'">
</div>' +
'<div ng-if="required"
ng-include="\'required.tpl.html\'">
</div>';
puis, en fonction de la valeur de maxLength
et required
, je peux charger dynamiquement l'un des 2 modèles, un seul d'entre eux à la fois est affiché si nécessaire.
J'espère que ça aide.