Ответ 1
Функция компиляции может использоваться для изменения DOM до того, как результирующая функция шаблона привязана к области.
Рассмотрим следующий пример:
<div my-directive></div>
Вы можете использовать функцию компиляции для изменения шаблона DOM следующим образом:
app.directive('myDirective', function(){
return {
// Compile function acts on template DOM
// This happens before it is bound to the scope, so that is why no scope
// is injected
compile: function(tElem, tAttrs){
// This will change the markup before it is passed to the link function
// and the "another-directive" directive will also be processed by Angular
tElem.append('<div another-directive></div>');
// Link function acts on instance, not on template and is passed the scope
// to generate a dynamic view
return function(scope, iElem, iAttrs){
// When trying to add the same markup here, Angular will no longer
// process the "another-directive" directive since the compilation is
// already done and we're merely linking with the scope here
iElem.append('<div another-directive></div>');
}
}
}
});
Таким образом, вы можете использовать функцию compile
, чтобы изменить шаблон DOM на все, что вам нравится, если это требует его директива.
В большинстве случаев tElem
и iElem
будет одним и тем же элементом DOM, но иногда он может быть другим, если директива клонирует шаблон для извлечения нескольких копий (см. ngRepeat
).
За кулисами Angular использует двухсторонний процесс рендеринга (компиляция + ссылка) для удаления копий скомпилированного фрагмента DOM, чтобы предотвратить Angular от необходимости обрабатывать (= директивы разбора) тот же DOM снова и снова для каждого экземпляра, если директива печатает несколько клонов, что приводит к значительно лучшей производительности.
Надеюсь, что это поможет!
ДОБАВИТЬ ПОСЛЕ КОММЕНТАРИИ:
Разница между функциями template
и compile
:
Функция шаблона
{
template: function(tElem, tAttrs){
// Generate string content that will be used by the template
// function to replace the innerHTML with or replace the
// complete markup with in case of 'replace:true'
return 'string to use as template';
}
}
Функция компиляции
{
compile: function(tElem, tAttrs){
// Manipulate DOM of the element yourself
// and return linking function
return linkFn(){};
}
}
Функция шаблона вызывается перед вызовом функции компиляции.
Несмотря на то, что они могут выполнять почти идентичные вещи и совместно использовать одну и ту же "подпись", ключевым отличием является то, что возвращаемое значение функции шаблона заменяет содержимое директивы (или полную разметку директивы, если replace: true
), тогда как ожидается, что функция компиляции изменит DOM программно и вернет функцию связи (или объект с функцией pre и post link).
В этом смысле вы можете думать о функции шаблона как о какой-то удобной функции, поскольку вам не нужно использовать функцию компиляции, если вам просто нужно заменить содержимое на строковое значение.
Надеюсь, что это поможет!