Понимание опции transclude определения директивы?

Я думаю, что это одна из самых сложных концепций для меня с помощью директивы angularjs.

В документе http://docs.angularjs.org/guide/directive говорится:

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

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

Это говорит transclude обычно используется с ngTransclude, Но образец из документа ngTransclude не использует ngTransclude директива вообще.

Я хотел бы несколько хороших примеров, чтобы помочь мне понять это. Зачем нам это нужно? Что это решает? Как это использовать?

6 ответов

Решение

Рассмотрим директиву myDirective в элементе, и этот элемент включает в себя некоторый другой контент, скажем:

<div my-directive>
    <button>some button</button>
    <a href="#">and a link</a>
</div>

Если myDirective использует шаблон, вы увидите, что содержимое <div my-directive> будет заменен вашим шаблоном директивы. Итак, имея:

app.directive('myDirective', function(){
    return{
        template: '<div class="something"> This is my directive content</div>'
    }
});

приведет к этому рендеру:

<div class="something"> This is my directive content</div> 

Обратите внимание, что содержание вашего оригинального элемента <div my-directive> будет потеряно (или лучше сказать, заменено). Итак, попрощайтесь с этими приятелями:

<button>some button</button>
<a href="#">and a link</a>

Так что, если вы хотите сохранить свой <button>... а также <a href>... в ДОМ? Вам понадобится то, что называется transclusion. Концепция довольно проста: включить контент из одного места в другое. Так что теперь ваша директива будет выглядеть примерно так:

app.directive('myDirective', function(){
    return{
        transclude: true,
        template: '<div class="something"> This is my directive content</div> <ng-transclude></ng-transclude>'
    }
});

Это сделало бы:

<div class="something"> This is my directive content
    <button>some button</button>
    <a href="#">and a link</a>
</div>. 

В заключение, вы в основном используете transclude, когда хотите сохранить содержимое элемента, когда используете директиву.

Мой пример кода здесь http://jsfiddle.net/7LRDS/1/ Вы также можете получить выгоду от просмотра: https://egghead.io/lessons/angularjs-transclusion-basics

Я думаю, что важно упомянуть изменения в вышеуказанном поведении в новой версии AngularJS. Я потратил один час, пытаясь достичь вышеупомянутых результатов с Angular 1.2.10.

Содержимое элемента с помощью ng-transclude не добавляется, а полностью заменяется.

Таким образом, в приведенном выше примере вы могли бы добиться с помощью transclude:

<div class="something">
    <button>some button</button>
    <a href="#">and a link</a>
</div>

и не

<div class="something"> This is my directive content
    <button>some button</button>
    <a href="#">and a link</a>
</div>

Благодарю.

То, что TechExplorer говорит, верно, но вы можете иметь оба содержимого, включив в свой шаблон простой тег контейнера (например, div или span) с атрибутом ng-transclude. Это означает, что следующий код в вашем шаблоне должен включать все содержимое

<div class="something"> This is my directive content <div class="something" ng-transclude></div></div>

Из вики:

"В информатике включение - это включение части или всего электронного документа в один или несколько других документов посредством ссылки".

Я хотел бы добавить другое использование для transclusion, и это - то, что это изменяет порядок выполнения функций компиляции и ссылки родительских и дочерних директив. Это может быть полезно, когда вы хотите скомпилировать дочерний DOM перед родительским DOM, поскольку родительский DOM, возможно, зависит от дочернего DOM. Эта статья углубляется и разъясняет это очень хорошо!

http://www.jvandemo.com/the-nitty-gritty-of-compile-and-link-functions-inside-angularjs-directives-part-2-transclusion/

Обновленная документация AngularJS 1.6.6 теперь имеет лучшее объяснение.

Transclude используется для создания директивы, которая охватывает другие элементы

Иногда желательно иметь возможность передавать весь шаблон, а не строку или объект. Допустим, мы хотим создать компонент "диалоговое окно". Диалоговое окно должно быть в состоянии обернуть любой произвольный контент.

Для этого нам нужно использовать опцию transclude. Обратитесь к примеру ниже.


script.js

angular.module('docsTransclusionExample', [])
.controller('Controller', ['$scope', function($scope) {
  $scope.name = 'Tobias';
}])
.directive('myDialog', function() {
  return {
    restrict: 'E',
    transclude: true,
    scope: {},
    templateUrl: 'my-dialog.html',
    link: function(scope) {
      scope.name = 'Jeff';
    }
  };
});

index.html

<div ng-controller="Controller">
  <my-dialog>Check out the contents, {{name}}!</my-dialog>
</div>

мой-dialog.html

<div class="alert" ng-transclude></div>

Скомпилированный вывод

<div ng-controller="Controller" class="ng-scope">
  <my-dialog class="ng-isolate-scope"><div class="alert" ng-transclude="">Check out the contents, Tobias!</div></my-dialog>
</div>

Transclude позволяет содержимому директивы с этой опцией иметь доступ к области видимости вне директивы, а не внутри.

Это показано в предыдущем примере. Обратите внимание, что мы добавили функцию link в script.js, которая переопределяет имя как Jeff. Обычно мы ожидаем, что {{name}} будет Джефф. Однако в этом примере мы видим, что привязка {{name}} по-прежнему является Tobias.

Лучшая практика: использовать только transclude: true когда вы хотите создать директиву, которая оборачивает произвольный контент.

transclude:true означает добавить все элементы, которые определены в вашей директиве, с элементом шаблона вашей директивы.

Если transclude:false, эти элементы не включены в ваш окончательный HTML-код директивы, только шаблон директивы отображается.

transclude: element означает, что ваш шаблон директивы не используется, только элемент, определенный в вашей директиве, отображается как html.

когда вы определяете свою директиву, тогда она должна быть ограничена E, а когда вы добавляете ее на страницу,

<my-directive><elements><my-directive>
<elements> is like <p>gratitude</p>
what i am talking about.
Другие вопросы по тегам