2016-06-02 3 views
0

У меня есть список в моем контроллере, который используется ng-repeat для создания моей директивы. В моей директиве я использую transclusion для добавления к элементу директивы.AngularJS: Transcluded содержимое в директиве исчезает

При добавлении первого элемента в мой список оно работает, как ожидалось, но при добавлении второго элемента скрытый контент исчезает из элемента первого элемента. Это не имеет никакого смысла для меня, поэтому должно быть что-то, что я недопонимаю.

Я создал example, который воссоздает проблему.

После добавления первого элемента, то HTML выглядит как ожидалось:

<div ng-controller="ctrl as c" class="ng-scope"> 
    <test ng-repeat="item in c.items track by $index" item="item" class="ng-scope ng-isolate-scope"> 
     <div class="ng-binding">1</div> 
     <span class="ng-scope">Transcluded</span> 
    </test> 
</div> 

После добавления второй элемент, содержание включены через больше не в элементе первого элемента!

<div ng-controller="ctrl as c" class="ng-scope"> 
    <test ng-repeat="item in c.items track by $index" item="item" class="ng-scope ng-isolate-scope"> 
     <div class="ng-binding">1</div> 
    </test> 
    <test ng-repeat="item in c.items track by $index" item="item" class="ng-scope ng-isolate-scope"> 
     <div class="ng-binding">2</div> 
     <span class="ng-scope">Transcluded</span> 
    </test> 
</div> 

HTML:

<div ng-app="ui"> 
    <div ng-controller="ctrl as c"> 
    <test ng-repeat="item in c.items track by $index" item="item">Transcluded</test> 
    </div> 
</div> 

Машинопись:

var app = angular.module('ui', []); 

class Controller { 
    public items = []; 

    constructor($timeout) { 
    $timeout(() => this.items.push({Id: 1}), 1000); 
    $timeout(() => this.items.push({Id: 2}), 2000); 
    } 
} 
app.controller('ctrl', ['$timeout', Controller] 

app.directive('test', function($compile) { 
    return { 
    scope: { 
     item: '=' 
    }, 
    transclude: true, 
    template: "<div>{{item.Id}}</div>" 
    link: function(scope, element, attrs, controller, transcludeFn) { 
     console.log("Appending transcluded content to " + scope.item.Id) 
     let e = transcludeFn(); 
     element.append(e); 
    } 
    }; 
}); 

JSFiddle: https://jsfiddle.net/rmytw9cr/2/

+0

использование нг-transclude атрибут с тестовой директивой, он может начать работать ... для получения дополнительной информации см http://teropa.info/blog/2015/06/09/transclusion.html – Ajay

ответ

1

Если вам не нужно использовать функцию transclude, не используйте его (контроль transclution на google для получения дополнительной информации, это немного сложнее, вы можете, например, скомпилировать транслируемый p искусство с учетом вашего выбора).

Вы можете использовать директиву transclude для простой переадресации.

Попробуйте следующий шаблон и удалить transclude из вашей директивы:

template: "<div><div>{{item.Id}}</div><div ng-transclude></div></div>" 

Update: Для использования функции перенаправления, вы должны понять, как это работает. Функция пересылки получает обратный вызов в качестве первого аргумента. Затем функция обратного вызова получает в качестве первого аргумента передаваемый элемент html.

Таким образом, правильный способ использовать его, будет:

transcludeFn(function(compiledHtml) { 
    // Do what ever you want with the complied HTML 
    // For example: element.append(compiledHtml); 
}); 

Функция может также включение получить еще один аргумент, который является областью для компиляции HTML с. В этом случае, вы должны поставить сферу в качестве первого аргумента, и обратный вызов с скомпилированного HTML как второй:

transcludeFn(someScope, function(compiledHtml) { 
    // Do what ever you want with the complied HTML 
    // For example: element.append(compiledHtml); 
}); 

И для окончательного - обратного вызова также может получить второй аргумент, который является включены через область применения:

transcludeFn(someScope, function(compiledHtml, transScope) { 
    // Do what ever you want with the complied HTML 
    // For example: element.append(compiledHtml); 
    // Here transScope will be the same as someScope 
}); 

transcludeFn(function(compiledHtml, transScope) { 
    // Do what ever you want with the complied HTML 
    // For example: element.append(compiledHtml); 
    // Here transScope will be the same as directive scope 
}); 
+0

Спасибо , что решает мою проблему. Однако мне все еще интересно, почему это не сработало, как я пытался. – meum

+0

Это потому, что работает функция пересылки. Когда вы вызываете функцию transclusion, вы предоставляете обратный вызов в качестве первого аргумента, где в этом обратном вызове первым аргументом является элемент transcluded.Я обновлю свой ответ на примере –

+0

Добавил обновление ответа –

Смежные вопросы