=====Transclude в директивах AngularJS===== Transclude - это возможность использовать первоначальное содержимое директивы в любом месте нашего шаблона. Давайте в файле index.html создадим дерективу foo-bar и опишем ее: Foo bar В коде, представленном выше, мы возвращаем объект, который указывает, что директива наша будет работать как елемент и выводим в console.log строку. Давайте убедимся, что все работает и откроем нашу страницу в браузере. Как видим, в инструментах для разработчика, строка отображается. {{ :angular:angularjs:custom_directive:directive21.png?600 |}} Далее добавляем шаблон. Для этого в описании директивы добавляем следующий код: var app = angular.module('app', []); app.directive('fooBar', function () { return { restrict: 'E', template: 'This is my super directive', link: function (scope, element, attrs) { console.log('This is my super directive'); } } }); {{ :angular:angularjs:custom_directive:directive22.png?600 |}} Теперь в браузере мы видим, что содержимое директивы заменилось на текст шаблона. Возникает вопрос: "Как сделать так, чтобы текст шаблона не пропадал и при этом мы могли его использовать?". Для этого был создан //transclude//. **Transclude - это еще одно property директивы**, в котором мы укажем true: var app = angular.module('app', []); app.directive('fooBar', function () { return { restrict: 'E', transclude: true, template: 'This is my super directive', link: function (scope, element, attrs) { console.log('This is my super directive'); } } }); После этого, в шаблоне, мы можем дописать следующий код: var app = angular.module('app', []); app.directive('fooBar', function () { return { restrict: 'E', transclude: true, template: 'This is my super directive
', link: function (scope, element, attrs) { console.log('This is my super directive'); } } });
Обновим страницу браузера. Теперь, как мы видим, к нашему шаблону - This is my super directive - добавился ng-transclude, который мы описали и внутри данного тега содержится тот текст, который мы изначально написали в директиве. {{ :angular:angularjs:custom_directive:directive23.png?600 |}} Повторим: для того, чтобы вывести первоначальное содержимое директивы в шаблоне - мы в описании директивы, в шаблоне, прописываем следующий код: \\ \\
Это стандартная директива Ангулара, которая позволяет вставить первоначальный текст в шаблон. Точно также мы можем использовать не div в качестве атрибута, а сам элемент ng-transclude. Тогда код будет выглядеть следующим образом: var app = angular.module('app', []); app.directive('fooBar', function () { return { restrict: 'E', transclude:true, template: 'This is my super directive ', link: function (scope, element, attrs) { console.log('This is my super directive'); } } }); Наш transclude точно также работает. Теперь усложним задачу. Обернем нашу диррективу в ng-controller и в директиве передадим, например, дополнительно некую переменную name. Для этого в файле index.html, после тега body, прописываем (не забываем подключить предварительно все необходимы для работы скрипты):
This is {{name}}
Давайте опишем переменную name в контроллере. Для этого создадим, собственно, сам контроллер app.controller, в который передаем два параметра - название контроллера и функцию с $scope. Внутри самого контроллера присваиваем $scope.name = 'Bob'. Смотрим, что у нас вышло. {{ :angular:angularjs:custom_directive:directive24.png?600 |}} Теперь у нас работает не только текст внутри директивы, но также отображаются и все переменные. ====Transclude - это функция==== Уберем ng-transclude, который мы добаили в шаблон, и посмотрим на функцию трансклуда в линк функции. Как это сделать? Мы имеем три параметра внутри линк-функции - это scope, element и attrs. Четвертым параметром передаем контроллер, а пятым - transclude. Именно этот пятый параметр нас сегодня и интересует.\\ \\ Что это такое? Transclude - это функция, которая первым параметром принимает scope, а вторым - функцию. Первый аргумент данной функции - clone, второй - scope. Давайте выведем console.log и посмотрим, что мы написали. Полный код: var app = angular.module('app', []); app.controller('firstCtrl', function ($scope) { $scope.name = 'Bob'; }); app.directive('fooBar', function () { return { restrict: 'E', transclude:true, template: 'This is my super directive', link: function (scope, element, attrs, ctrl, transclude) { console.log('This is my super directive'); transclude(scope, function(clone, scope) { console.log('!', clone, scope); }); } } }); Обновляем страницу, смотрим в консоль. {{ :angular:angularjs:custom_directive:directive25.png |}} Видим, что первый параметр **clone - передает span**, который будет непосредственно добавляться в конец нашего шаблона. то есть по факту - это //This is {{name}}//. **Вторым параметром идет scope** клонируемого элемента, в данном случае - это все тот же //This is {{name}}.// \\ Теперь добавим element - им будет выступать наша дирректива: var app = angular.module('app', []); app.controller('firstCtrl', function ($scope) { $scope.name = 'Bob'; }); app.directive('fooBar', function () { return { restrict: 'E', transclude:true, template: 'This is my super directive', link: function (scope, element, attrs, ctrl, transclude) { console.log('This is my super directive'); transclude(scope, function(clone, scope) { console.log('!', clone, scope); element.append(clone); }); } } }); Что мы сейчас сделали? Мы взяли наш элемент - это шаблон 'This is my super directive', который будет добавляться в самый конец. Clone - это как раз наш span, который содердит в себе This is {{name}}.\\ \\ Давайте посмотрим, что у нас получилось. Все работает в точности так, как и работало. У нас есть дирректива, также шаблон 'This is my super directive', и добавился span с содержимым 'This is Bob'. {{ :angular:angularjs:custom_directive:directive26.png?600 |}} Когда мы используем transclude в виде функции - мы можем легко оперировать теми значениями, которые мы хотим добавить в конец шаблона, и таким же путем мы можем получить scope элемента.