Директивы Angular как веб-компоненты - зачем требовать?

0

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

Мне часто нужны компоненты, которые находятся в текущей. Другими словами, если компонент A состоит из B и C, для этого часто требуется API B и C, чтобы он мог функционировать. Угловое не позволяет требовать компонентов, которые находятся ниже в иерархии DOM (я считаю). Я обнаруживаю, что использую схему событий, где после активации B и C они испускают событие и передают себя в качестве аргумента. Затем A обрабатывает эти события, захватывает ссылку B и C, а затем останавливает распространение двух событий.

Подумав об этом, он кажется обратным. Для меня компонент должен иметь возможность ссылаться на компоненты, из которых он состоит. Не следует ли связывать директивы снизу вверх, а не сверху вниз? Я имею в виду, что если компонент должен быть автономным черным ящиком, который предоставляет API для окружающего мира, он не должен требовать компонентов, которые вне его. Это разрушает разделение между компонентами и, кажется, соединяет их. Однако, требуя вещей внутри себя, кажется, необходимо...

В основном, я задаю два вопроса: 1) Какая логика требует от снаружи (и не требует от нее), кроме "Так было построено Угловое"? 2) Является ли схема, которую я использую ($ emitting events при активации директивы) хорошей, или есть лучший способ захвата директив изнутри?

Заранее спасибо.

  • 0
    Можете ли вы проиллюстрировать пример кода?
  • 0
    Я чувствую, что вы можете смотреть на это неправильно. Дочерние объекты всегда требуют своих родителей. Родитель должен предоставлять функции API, которые может использовать дочерний элемент, а не дочерний элемент, предоставляющий API родительскому элементу. Родитель должен иметь возможность продолжать функционировать, даже если ребенок не существует. Это отражает поведение DOM; <div> может отображаться, даже если у него нет дочернего элемента, например.
Показать ещё 9 комментариев
Теги:

1 ответ

0

Ваш пример кода нарушает принцип инкапсуляции:

Пример нарушает принцип инкапсуляции

angular.module('app').controller('coolTextBoxCtrl', coolTextBoxCtrl)
function coolTextBoxCtrl($scope) {
    var vm = this;

    vm.enabled = true;
    vm.model = '';

    activate();

    function activate() {
        console.log('publishing $scope');
        $scope.$emit('coolTextBoxActivated', vm);
    }
}

Публикуя изоляционную область для использования в мире, этот пример нарушает инкапсуляцию, которая является одним из четырех основополагающих принципов объектно-ориентированного программирования. Инкапсуляция используется для скрытия значений или состояния структурированного объекта данных внутри класса, что препятствует прямому доступу к ним неавторизованных сторон. 1

Лучший подход - использовать bind-to-controller.

angular.module('app').directive('coolTextBox', coolTextBox)
function coolTextBox() {
    return {
        restrict: 'E',
        controller: 'coolTextBoxCtrl as ctbc',
        template: '<input ng-model="ctbc.model">'+
                  '<p ng-style="{\'font-weight\': '+
                        'ctbc.enabled?\'bold\':\'\'}">'+
                  'scope-{{$id}}</p>'+
                  '{{ctbc}}'+
                  '<hr>',
        scope: {
            model: '=cbtModel',
            enabled: '=enabled'
        },
        bindToController: true
    }
}

Затем выведите общедоступные переменные, используя атрибуты.

    <cool-text-box
       enabled="cfc.ctbc.enabled"
       cbt-model="cfc.ctbc.model"
    ></cool-text-box>

Дополнительные сведения о bindToController см. В разделе " Справочник по bindToController компиляции AngularJS" - API всеобъемлющей директивы

Обновленный ДЕМО на PLNKR.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню