Когда использовать transclude 'true' и transclude 'element' в Angular?

176

Когда я должен использовать transclude: 'true'и когда transclude: 'element'? Я не могу ничего найти transclude: 'element'в угловых документах, они довольно запутанные.

Я был бы счастлив, если бы кто-то мог объяснить это простым языком. В чем выгода каждого варианта? В чем реальная разница между ними?

Вот что я нашел:

transclude: true

Внутри функции компиляции вы можете манипулировать DOM с помощью функции связывания transclude или вставить вставленный DOM в шаблон, используя директиву ngTransclude для любого тега HTML.

и

transclude: element

Это включает весь элемент, и в функцию компиляции введена функция связывания transclude. Вы не можете иметь здесь доступ к области, потому что область еще не создана. Функция компиляции создает функцию ссылки для директивы, которая имеет доступ к области, а transcludeFn позволяет вам касаться клонированного элемента (который был включен) для манипулирования DOM или использовать данные, связанные с областью действия в нем. Для вашей информации, это используется в ng-repeat и ng-switch.

LauroSkr
источник

Ответы:

229

Из документации AngularJS по директивам :

transclude- скомпилируйте содержимое элемента и сделайте его доступным для директивы. Обычно используется с ngTransclude. Преимущество включения состоит в том, что функция связывания получает функцию включения, которая предварительно привязана к правильной области видимости. В типичной настройке виджет создает изолированную область видимости, но включение не дочерний, а родственный элемент изолированной области видимости. Это позволяет виджету иметь частное состояние, а включение может быть привязано к родительской (предизолятной) области видимости.

true - включить содержание директивы.

'element' - включить весь элемент, включая любые директивы, определенные с более низким приоритетом.

transclude: true

Так скажем , у вас есть директива под названием my-transclude-trueобъявлено с transclude: trueкоторый выглядит следующим образом :

<div>
  <my-transclude-true>
    <span>{{ something }}</span>
    {{ otherThing }}
  </my-transclude-true>
</div>

После компиляции и до ссылки это становится:

<div>
  <my-transclude-true>
    <!-- transcluded -->
  </my-transclude-true>
</div>

В содержании (дети) из my-transclude-trueкоторых <span>{{ something }}</span> {{..., является и доступны включен через директиву.

transclude: 'element'

Если у вас есть директива my-transclude-elementс объявленным объявлением, transclude: 'element'которая выглядит так:

<div>
  <my-transclude-element>
    <span>{{ something }}</span>
    {{ otherThing }}
  </my-transclude-element>
</div>

После компиляции и до ссылки это становится:

<div>
   <!-- transcluded -->
</div>

Здесь весь элемент, включая его дочерние элементы, включается и становится доступным для директивы.

Что происходит после ссылки?

Это зависит от вашей директивы делать то, что нужно делать с функцией transclude. ngRepeatиспользует transclude: 'element'для повторения всего элемента и его дочерних элементов при изменении области действия. Однако, если вам нужно только заменить тег и хотите сохранить его содержимое, вы можете использовать transclude: trueс ngTranscludeдирективой , которая делает это для вас.

Sirhc
источник
3
Я вроде пропустил made available to the directiveутверждение. Элемент всегда доступен для директивы. не могли бы вы уточнить это?
парень mograbi
1
@guymograbi Это предложение может иметь больше смысла, так как «доступно директиве через функцию, предварительно привязанную к правильной области видимости ».
Мишель Тилли
Как один модуль может проверить директиву с transclude, равным 'element'? В настоящее время я борюсь с этой проблемой. Кажется, я не могу получить доступ к элементу после его включения.
Честер Ривас
33

Если установлено значение true, директива удаляет исходный контент, но делает его доступным для повторной вставки в шаблон через директиву ng-transclude.

appModule.directive('directiveName', function() {
    return {
      template: '<div>Hello there <span ng-transclude></span></div>',
      transclude: true
    };
});


<div directive-name>world</div>

Браузер отображает: «Привет, мир!»

Андре Дион
источник
23
Это не отвечает на вопрос вообще (который был о разнице между transclude: trueи transclude: element)
Джаспер
1
Также было бы интересно узнать, какие теги DOM браузера имеет после директивы, а не то, что она читает ...
kontur
8

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

Когда дело доходит до angular, у нас есть какой-то контроллер с его областью действия, и внутри него мы поместим директиву, которая поддерживает transclusion. Эта директива будет иметь свой собственный дисплей и функциональность. В непереходной директиве содержание внутри директивы определяется самой директивой, но с помощью включения, как в случае с рамкой рисунка, мы можем решить, что будет внутри директивы.

angular.module("app").directive('myFrame', function () {
    return {
        restrict: 'E',
        templateUrl:"frame.html",
        controller:function($scope){
          $scope.hidden=false;
          $scope.close=function(){
            $scope.hidden=true;

          }
        },
        transclude:true


    }

});

Содержание внутри директивы

<div class="well" style="width:350px;" ng-hide="hidden">

  <div style="float:right;margin-top:-15px">
    <i class="glyphicon glyphicon-remove" ng-click="close()" style="cursor:pointer"></i> 
  </div>
  <div ng-transclude>
    /*frame content goes here*/
  </div>
</div>

Директива о звонках

<body ng-controller="appController">
    <my-frame>
      <span>My Frame content</span>
    </my-frame>
  </body>

пример

Код-EZ
источник
Тем не менее я не понял transclude, у вас может быть какая-нибудь простая программа для иллюстрации этого?
Раджа