Понимание опции 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. Эта статья углубляется и разъясняет это очень хорошо!
Обновленная документация 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.