AngularJS - динамический шаблон директивы
Как создать директиву с динамическим шаблоном?
'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.
Ответы
Ответ 1
Была аналогичная потребность. $compile
выполняет задание. (Не совсем уверен, что это "THE" способ сделать это, все еще работая через angular)
http://jsbin.com/ebuhuv/7/edit - мое исследование.
Одно замечание (в моем примере), одним из моих требований было то, что шаблон изменился бы на основе атрибута type
после того, как вы нажмете на сохранение, и шаблоны были совсем другими. Итак, вы получаете привязку данных, если вам нужен новый шаблон, вам придется перекомпилировать.
Ответ 2
Я использовал $templateCache для выполнения чего-то подобного. Я поместил несколько ng-шаблонов в один html файл, который я ссылаюсь на шаблон директивы templateUrl. что гарантирует, что html доступен для кеша шаблона. то я могу просто выбрать по id, чтобы получить нужный шаблон ng.
template.html:
<script type="text/ng-template" id="foo">
foo
</script>
<script type="text/ng-template" id="bar">
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);
}
};
}]);
Ответ 3
Вы должны перенести свой переключатель в шаблон с помощью директивы 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="[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>
Ответ 4
Если вы хотите использовать директиву AngularJs с динамическим шаблоном, вы можете использовать эти ответы, но здесь больше профессиональный и юридический. Вы можете используйте templateUrl не только с одним значением. Вы можете использовать его как функцию, которая возвращает значение как url . Эта функция имеет некоторые аргументы, которые вы можете использовать.
http://www.w3docs.com/snippets/angularjs/dynamically-change-template-url-in-angularjs-directives.html
Ответ 5
Мне удалось справиться с этой проблемой. Ниже приведена ссылка:
https://github.com/nakosung/ng-dynamic-template-example
с конкретным файлом:
https://github.com/nakosung/ng-dynamic-template-example/blob/master/src/main.coffee
dynamicTemplate
динамический шаблон директивных хостов, который передается в пределах области видимости, и размещенный элемент действует как другие собственные angular элементы.
scope.template = '< div ng-controller="SomeUberCtrl">rocks< /div>'
Ответ 6
Один из способов использования функции шаблона в вашей директиве:
...
template: function(tElem, tAttrs){
return '<div ng-include="' + tAttrs.template + '" />';
}
...
Ответ 7
Я был в той же ситуации, мое полное решение опубликовано здесь
В основном я загружаю шаблон в директиву таким образом
var tpl = '' +
<div ng-if="maxLength"
ng-include="\'length.tpl.html\'">
</div>' +
'<div ng-if="required"
ng-include="\'required.tpl.html\'">
</div>';
то в соответствии со значением maxLength
и required
я могу динамически загружать один из двух шаблонов, при необходимости указывается только один из них.
Я надеюсь, что это поможет.