Подтвердить что ты не робот

Каковы преимущества функции шаблона директивы в Angularjs?

Согласно документации a template может быть функцией, которая принимает два параметра: element и attributes и возвращает строковое значение, представляющее шаблон. Он заменяет текущий элемент содержимым HTML. Процесс замещения переносит все атрибуты и классы из старого элемента в новый.

Функция compile имеет дело с преобразованием шаблона DOM. Он принимает три параметра: element, attributes и transclude. Параметр transclude устарел. Он возвращает функцию link.

Похоже, что функции template и a compile очень похожи и могут достичь того же. Функция template определяет шаблон, а функция compile изменяет шаблон DOM. Однако это можно сделать в самой функции template. Я не понимаю, зачем изменять шаблон DOM вне функции template. И наоборот, если DOM можно изменить в функции compile, то какая потребность в функции template?

4b9b3361

Ответ 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).

В этом смысле вы можете думать о функции шаблона как о какой-то удобной функции, поскольку вам не нужно использовать функцию компиляции, если вам просто нужно заменить содержимое на строковое значение.

Надеюсь, что это поможет!

Ответ 2

Одним из лучших применений функции шаблона является условное создание шаблона. Это позволяет автоматизировать создание шаблона на основе атрибута.

Я видел очень большие шаблоны, которые используют ng-if, чтобы скрыть разделы шаблона. Но вместо этого он бросает все в шаблон и использует ng-if, что может вызвать чрезмерное связывание, вы можете удалить разделы DOM из шаблона, который никогда не будет использоваться.

Скажем, у вас есть директива, которая будет включать либо под-директиву item-first, либо item-second. И суб-директива никогда не изменится для жизни внешней директивы. Вы можете настроить шаблон до вызова функции компиляции.

<my-item data-type="first"></my-item>
<my-item data-type="second"></my-item>

И строка шаблона для них:

<div>
  <item-first></item-first>
</div>

и

<div>
  <item-second></item-second>
</div>

Я согласен, что это предельное упрощение, но у меня есть очень сложные директивы, и внешняя директива должна отображать одну из 20 разных внутренних директив на основе типа. Вместо использования transclude я могу установить тип во внешней директиве и заставить функцию шаблона генерировать правильный шаблон с правильной внутренней директивой.

Затем правильно отформатированная строка шаблона передается функции компиляции и т.д.