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

Angular 1,5 компонента против старой директивы - где функция связи?

Я прочитал эту замечательную недавнюю статью о новом помощнике .component() в Angular 1.5, который должен помочь каждому перейдите в Angular 2. Все выглядит красиво и просто, но я не мог найти никакой информации о манипуляциях с DOM внутри компонентов.

Однако существует свойство template, которое может быть функцией и принимать аргументы $element и $attrs. Еще мне непонятно, есть ли замена для функции link. Это не похоже.

4b9b3361

Ответ 1

РЕДАКТИРОВАТЬ 2/2/16: документация 1.5 теперь охватывает компоненты: https://docs.angularjs.org/guide/component


Некоторые мысли, основанные на чтении (ссылки ниже):

  • Компоненты не являются заменой для директив. Компонент - это особый тип директивы, которая организует контроллер с помощью шаблона.

  • Компоненты не имеют функции связи, а контроллеры по-прежнему находятся не там, где вы будете обрабатывать DOM-манипуляции

  • Если вам нужна манипуляция DOM, ваш компонент может использовать другие директивы, которые включают эту манипуляцию DOM в функцию ссылки.

Мне потребовалось некоторое время, чтобы понять это, но как только я это сделал, это имело некоторый смысл: компоненты - это директивы, но не все директивы являются - или должны быть - компонентами.

Вопрос о ссылочных функциях является естественным или был для меня, когда я думал, что компоненты заменяют директивы. Зачем? Потому что нас учили помещать манипуляции с DOM в функцию директивной ссылки: "Директивы, которые хотят модифицировать DOM, обычно используют опцию ссылки для регистрации слушателей DOM, а также для обновления DOM". https://docs.angularjs.org/guide/directive.

Если вы работаете с этим предположением (компоненты заменяют директивы), то вы обнаружите, что документы Angular не отвечают на вопрос, потому что, ну, это не правильный вопрос, если вы знаете назначение компонента. (Компоненты описаны в документации $ compileProvider, а не в директивной документации.)

Фоновое чтение

То, что я говорю выше, на самом деле является перефразировкой того, что сказал Тодд Мотто в, пожалуй, лучшем (пока) обсуждении компонентов и директив:

https://www.reddit.com/r/angularjs/comments/3taxjq/angular_15_is_set_to_introduce_the_component/

Было бы полезно вытащить эти комментарии в более общую статью.

Большинство статей о компонентах не упоминают функцию ссылки (это не значит, что это не отличные статьи):

https://toddmotto.com/exploring-the-angular-1-5-component-method/

https://medium.com/@tomastrajan/component-paradigm-cf32e94ba78b#.vrbo1xso0

https://www.airpair.com/angularjs/posts/component-based-angularjs-directives

Или, когда упоминается функция ссылки, она указана в скобках:

http://teropa.info/blog/2015/10/18/refactoring-angular-apps-to-components.html

В одной статье говорится, что компоненты "используют контроллеры вместо функций связи". Но это не "взамен" ситуация: контроллеры не заменяют функции связи.

Ответ 2

Это упрощает запись приложения таким образом, который аналогичен использованию веб-компонентов или с использованием архитектуры приложения Angular 2.

Преимущества компонентов:

более простая конфигурация, чем простые директивы, способствуют нормальным значениям по умолчанию и передовые методы, оптимизированные для написания архитектуры на основе компонентов чтобы упростить обновление до Angular 2

Если не использовать Компоненты:

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

Ответ 3

Обновление (с 22 августа 2017 года): $ inject рекомендуется для этого в AngularJS. Читайте Styleguide: ссылка Styleguide и документы AngularJS: Документы AngularJS

Для использования привязок DOM в компонентах вместо создания директивы со ссылкой, вы можете ввести "$ element" или другую службу, которая вам нужна в вашей функции контроллера, например

app.component('pickerField', {
    controller: PickerField,
    template: '<span>Your template goes here</span>'
  });

  PickerField.$inject = ['$element'];

  function PickerField(element) {
    var self = this;
    self.model = self.node.model;
    self.open = function() {
      console.log('smth happens here');
    };
    element.bind('click', function(e) {
      console.log('clicked from component', e);
      self.open();
    });
  }

Ответ 4

Итак, похоже, что контроллер сейчас подходит для него, поскольку он является единственным возможным. Также мы не можем использовать опцию replace в вспомогательном компоненте.

Ответ 5

Вы можете использовать функцию $ postLink(), которая находится в новейшей версии.

Подобно функции post-link, этот хук может использоваться для настройки обработчиков событий DOM и выполнения прямых манипуляций с DOM.

Ответ 6

В соответствии с текущей документацией Angular2 (см. https://github.com/angular/angular/blob/master/modules/angular2/docs/core/02_directives.md) все еще будут директивы в Angular2. Таким образом, вы сможете использовать как @Directive, так и @Component, где:

  • Директивы полезны для инкапсуляции поведения.
  • Компонент - это директива, которая использует shadow DOM для создания инкапсуляции визуального поведения. Компоненты обычно используются для создания виджета пользовательского интерфейса или для разбивки приложения на более мелкие компоненты.

Итак, если вам нужна манипуляция DOM, вам нужно будет использовать @Directive, поэтому Angular.directive в Angular 1.x. Связывание событий может быть выполнено с использованием свойств host. Что касается манипуляции с DOM как таковой, все еще отсутствует документация (например, https://github.com/angular/angular/blob/master/modules/angular2/docs/core/09_compilation.md или https://github.com/angular/angular/blob/master/modules/angular2/docs/core/08_lifecycle.md), но вы можете искать Lifecycle, как предлагается здесь fooobar.com/info/106944/....

Как короткий ответ, Angular 1.5+, продолжайте использовать angular.directive, если у вас есть доступ DOM, иначе инкапсулируйте в angular.component. Также старайтесь как можно меньше уменьшить использование $scope для события, отличного от dom, и предпочесть RxJS, для которого см. https://medium.com/front-end-developers/managing-state-in-angular-2-using-rxjs-b849d6bbd5a5#.obgb6dl6n,