#angularjs
#angularjs
Вопрос:
Можно ли решить, применять ли преобразование к элементу на основе переменной области видимости?
Например (глупый упрощенный сокращенный пример того, чего я пытаюсь достичь)
app.directive('myHighlight', function () {
return {
transclude : true,
template : "<div style='border:1px solid red'><span ng-transclude></span></div>"
}
});
app.directive('myDirective', function () {
return {
template : "<span>some text</span>",
link : function (scope,element,attr) {
if ( 'shouldHighlight' in attr) {
// wrap this directive with my-highlight
}
}
}
});
А затем в html
<span my-directive></span>
<span my-directive should-highlight></span>
Примечание, пожалуйста, не говорите мне просто добавить выделение вместо should-highlight, как я уже сказал, это глупый сокращенный пример. Спасибо.
Ответ №1:
Вместо того, чтобы необязательно применять директиву выделения, всегда применяйте ее и выполняйте необязательный перенос внутри этой директивы. Необязательный перенос достигается с ng-if
помощью и логического значения, передаваемого из myDirective
в myHighlight
через разметку:
<div my-highlight="someBooleanValue">some text</div>
Шаблон myHighlight
:
<div ng-if="actuallyTransclude" style="border:1px solid red">
<span ng-transclude></span>
</div>
<div ng-if="!actuallyTransclude" ng-transclude></div>
Рабочий jsfiddle: http://jsfiddle.net/wilsonjonash/X6eB5 /
Комментарии:
1. Спасибо за совет, но моя проблема в том, что переданная директива передается как метаданные, поэтому я пытаюсь найти способ ввести ее по имени (аналогично службе $controller). Мне нужно условно применить разные транслюдированные директивы к разным шаблонам.
2. ах, хорошо. как насчет того, чтобы проголосовать за усилия? 😉
Ответ №2:
Конечно. Когда вы указываете параметр transclude, вы знаете, что можете декларативно указать, куда должен идти контент, используя ng-transclude .
В функции связывания директивы вы также получите ссылку на функцию преобразования (https://docs.angularjs.org/api/ng/service /$compile, см. раздел ссылки):
function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }
transcludeFn вернет переведенное содержимое, поэтому вы можете условно вставлять то, что было и когда вы хотите, в функцию ссылки вашей директивы.
Пример (http://jsfiddle.net/DKLY9/22 /)
HTML
<parentdir flg="1">
Child Content
</parentdir>
JS
app.directive('parentdir', function(){
return {
restrict : 'AE',
scope: {
flg : "="
},
transclude : true,
template : "<div>Parent {{childContent}} Content</div>",
link : function(scope, elem, attr, ctrl, transcludeFn){
if (scope.flg==1){
scope.childContent="Include Me instead";
}
else {
scope.childContent = transcludeFn()[0].textContent;
}
}
}
});
Это упрощенный пример. Чтобы получить лучшее представление о том, как использовать функцию transclude, обратитесь к следующему: http://blog.omkarpatil.com/2012/11/transclude-in-angularjs.html
Ответ №3:
Когда я подхожу к такого рода проблемам, я просто смотрю на то, что сделал angular. Обычно их исходный код очень удобочитаем и прост в повторном использовании. ngTransclude ничем не отличается:
https://github.com/angular/angular.js/blob/master/src/ng/directive/ngTransclude.js
Остальное я оставляю вам. Вы можете либо создать свою собственную директиву преобразования, которая также получает условие, либо просто дублировать код в вашу конкретную директиву, когда условие if имеет значение true.
Если у вас все еще есть проблемы, пожалуйста, дайте мне знать, и мы настроим plunker.