Переключить в AngularJS без добавления нового элемента
Есть ли способ перевести какой-либо контент в директиву без добавления дополнительных элементов.
Например
директива:
{
scope: {
someParam: "="
},
link: function(scope, element, attrs){
//do something
},
transclude: true,
template:'<div ng-transclude></div>'
}
source html:
<div my-directive some-param="somethingFromController">
my transcluded content: {{somethingElseFromController}}
</div>
В этом примере добавляется дополнительный div для разметки. Обычно это было бы неплохо, но я пытаюсь использовать эту директиву внутри таблицы, поэтому добавление тега div заставляет задуматься.
Я также попытался не указывать transclude
или template
, который избавляется от дополнительного тега div, но теперь {{somethingElseFromController}}
не может быть найден, поскольку содержимое "transcluded" находится в изолированной области. Я знаю, что могу просто получить параметры для моей директивы от объекта attrs в функции связывания вместо создания изолированной области, но я бы предпочел избежать необходимости оценивать строки с областью. $Apply().
Кто-нибудь знает, как это сделать?
Спасибо!
Ответы
Ответ 1
Это возможно с помощью Angular. Такие директивы, как ng-repeat, делают это. Вот как вы это делаете:
{
restrict: 'A',
transclude: true,
compile: function (tElement, attrs, transclude) {
return function ($scope) {
transclude($scope, function (clone) {
tElement.append(clone);
});
};
}
};
Итак, что здесь происходит? Во время связывания мы просто добавляем клон, который является элементом, который мы пытаемся перевести, в элемент директивы. Angular применит $scope к элементу clone, чтобы вы могли сделать все Angular доброту внутри этого элемента.
Ответ 2
Что ответил @Vakey, это то, что я искал.
Но как сегодня в документации Angular говорится:
Функция transclude, которая передается функции compile
, устарела, как это, например, не знает о правильном внешнем объеме. Пожалуйста, используйте функцию transclude, которая передается функции связи.
Поэтому вместо controller
(на данный момент) и его функции $transclude
я использовал controller
как часть примера, представленного в документации $compile:
controller: function($scope, $element, $transclude) {
var transcludedContent, transclusionScope;
$transclude(function(clone, scope) {
$element.append(clone);
transcludedContent = clone;
transclusionScope = scope;
});
},
Ответ 3
Подробнее о записи @rob...
Transclusion требует, чтобы Angular создавал элемент, который является клоном содержимого любого тега, в котором действует/живет директива. Если содержимое является текстом, оно завершает его в промежутке.
Это значит, что у него есть элемент DOM, чтобы применить область к тому, когда вызывается $compile.
Итак, в основном transclude добавляет элемент по той же причине, что вы не можете $compile('plain text here {{wee}}')
.
Теперь вы можете сделать что-то вроде того, что вы пытаетесь сделать с $interpolate, что позволяет применять scope для привязок в строке типа "blah {{foo}}".... но поскольку я действительно не уверен, что вы пытаетесь сделать, я не могу дать вам конкретный пример.