=====Transclude element в директивах AngularJS=====
**transclude: ‘element’** - трансклюдирует весь элемент, и функция связывания трансклюда вводится в функцию компиляции. Вы не можете иметь доступ к области здесь, потому что область еще не создана. Compile function создает функцию связи для директивы, которая имеет доступ к scope, и transcludeFn позволяет коснуться клонированного элемента (который был трансклинирован) для манипуляции DOM или использовать данные, привязанные к scope в нем. Для вашего сведения, это используется в ng-repeat и NG-switch.\\
Попробуем разобраться что такое **transclude: element** и как оборачивать директиву в дополнительную разметку.\\
Для начала создадим форму.\\
Мы будем добавлять директиву на елемент формы. Назовем директиву wrap-in и передадим параметр red.\\
Давайте создадим директиву
app.directive('wrapIn', function () {
return {
link: function (scope, element, attrs) {
console.log('wrapIn');
}
};
});
В консоли у нас вывелось wrapIn.
{{ :angular:angularjs:custom_directive:directive27.png |}}
Теперь добавим поле transclude.
app.directive('wrapIn', function () {
return {
transclude: 'element',
link: function (scope, element, attrs) {
console.log('wrapIn');
}
};
});
Как мы видим в браузере, весь контент у нас пропал. Давайте напишем текст до формы, чтобы видеть что происходит
My form here
Как мы видим, в инспекте елементов есть надпись** "My form here"**, а дальше идет комментарий **wrapIn: red**. Когда мы используем transclude, то у нас остается такой комментарий, чтобы было видно, что здесь должна применятся директива.\\
{{ :angular:angularjs:custom_directive:directive28.png |}}
Теперь давайте передадим в линк функцию пятым параметром transclude.
link: function (scope, element, attrs, ctrl, transclude) {
console.log('wrapIn');
transclude(scope, function (clone) {
console.log(clone);
});
}
Мы вызвали функцию transclude с пераметром scope и функцией, где первым параметром идет clone.\\
\\
В консоли мы видим,что clone - это наша форма, которая сейчас находится в transclude. Как мы видим, это полностью наш елемент, на который мы повесили директиву. Не его содержимое, а весь елемент. Это главное отличие **transclude = element** от **transclude = true**.\\
\\
Теперь давайте создадим в body script.
Зачем мы это делаем? Мы хотим потом в директиве из templateCache достать шаблон.\\
Теперь давайте в нашу директиву заинджектим templateCache.
app.directive('wrapIn', function () {
return {
transclude: 'element',
link: function (scope, element, attrs, ctrl, transclude) {
var template = $templateCache.get(attrs.wrapIn);
console.log('wrapIn', template);
transclude(scope, function (clone) {
console.log(clone);
});
}
};
});
attrs.wrapIn берет аргумент директивы wrap-in и означает red. В скрипте у нас id нашего шаблона red. То есть мы хотим из templateCache выгрести шаблон с id red.\\
В консоли вывелся наш шаблон.
{{ :angular:angularjs:custom_directive:directive29.png |}}
Теперь мы хотим сгенерировать новый елемент.
app.directive('wrapIn', function ($templateCache) {
return {
transclude: 'element',
link: function (scope, element, attrs, ctrl, transclude) {
var template = $templateCache.get(attrs.wrapIn);
var templateElement = angular.element(template);
transclude(scope, function (clone) {
element.after(templateElement.append(clone));
});
}
};
});
В templateElement будет уже записан не string, а созданный DOM елемент. Далее в наш елемент, который пустой, так как срабатывает transclude добавляем templateElement и внутрь аппендим clone. clone как вы помните - это наша форма.\\
В браузере мы видим, что наша форма выводится. И мы видим, что у нас красные стили из-за того, что все форма обернута в класс red.\\
{{ :angular:angularjs:custom_directive:directive30.png |}}
Так очень легко оборачивать директиву в какой-то нужный вам контент. Давайте создадим еще один скрипт с id=table.\\
В директиве wrap-in передадим параметр table.
В браузере мы видим, что у нас вывелся дополнительный контент перед формой. Это тоже удобно, когда мы можем сгенерировать часть контента вне директивы, а потом просто сгенерировать шаблон.\\
{{ :angular:angularjs:custom_directive:directive31.png |}}
Главное, что вы должны заполнить из этого видео, что transclude = element позволяет делать transclude всей директивы сразу. Не содержимого блока, а всего блока.