Подтвердить что ты не робот

Переключить в 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().

Кто-нибудь знает, как это сделать? Спасибо!

4b9b3361

Ответ 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}}".... но поскольку я действительно не уверен, что вы пытаетесь сделать, я не могу дать вам конкретный пример.