Зв'язок між вкладеними директивами


61

Здається, існує досить багато способів комунікації між директивами. Скажімо, ви вклали директиви, де внутрішні директиви повинні щось повідомляти зовнішньому (наприклад, це було обрано користувачем).

<outer>
  <inner></inner>
  <inner></inner>
</outer>

Поки що у мене є 5 способів зробити це

require: батьківська директива

innerДиректива може зажадати outerдирективу, яка може поставити під який - або метод на своєму контролері. Так у innerвизначенні

require: '^outer',
link: function(scope, iElement, iAttrs, outerController) {
   // This can be passed to ng-click in the template
   $scope.chosen = function() {
     outerController.chosen(something);
   }
}

І в outerконтролері директиви:

controller: function($scope) {
   this.chosen = function(something) {
   }
}

$emit подія

innerДиректива може $emitподія, якого outerдиректива може реагувати, через $on. Отже, в innerконтролері директиви:

controller: function($scope) {
  $scope.chosen = function() {
    $scope.$emit('inner::chosen', something);
  }
}

і в outerконтролерах директив:

controller: function($scope) {
  $scope.$on('inner::chosen, function(e, data) {
  }
}

Виконати вираз у батьківській області, через &

Елемент може прив'язати до виразу в батьківській області та виконати його у відповідній точці. HTML буде таким:

<outer>
  <inner inner-choose="functionOnOuter(item)"></inner>
  <inner inner-choose="functionOnOuter(item)"></inner>
</outer>

Таким чином, innerконтролер має функцію 'InternalChoose', яку він може викликати

scope: {
  'innerChoose': '&'
},
controller: function() {
  $scope.click = function() {
    $scope.innerChoose({item:something});
  }
}

яка б називала (в даному випадку) функцією "functionOnOuter" в області outerдирективи:

controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}

Сфера успадкування за неізольованою сферою

З огляду на те, що це вкладені контролери, успадкування сфери може працювати, і внутрішня директива може просто викликати будь-які функції ланцюга області, доки вона не має ізольованої області). Отже, в innerдирективі:

// scope: anything but a hash {}
controller: function() {
  $scope.click = function() {
    $scope.functionOnOuter(something);
  }
}

І в outerдирективі:

controller: function($scope) {
  $scope.functionOnOuter = function(item) {
  }
}

Службовим шляхом вводять як внутрішнє, так і зовнішнє

Служба може бути введена в обидві директиви, тому вони можуть мати прямий доступ до одного і того ж об'єкта, або викликати функції для сповіщення служби, а може навіть зареєструватися для отримання сповіщення у паб / підсистемі. Для цього не потрібно вводити директиви.

Запитання : Які можливі недоліки та переваги кожного перед іншими?


5
Я не можу повірити, що раніше цього питання не бачив. Я ціную всі варіанти, які ви надали. Якщо ви ще цього не зробили, чи думали ви розмістити це питання в stackoverflow? Я би сподівався, що він отримає набагато більше тяги на stackoverflow.
Майк Барлоу - BarDev

Будь ласка, дивіться цю пропозицію - softwareengineering.stackexchange.com/questions/344165/…
yellowblood

Відповіді:


7

&Я вважаю за краще визначити атрибут в області директив, перш за все тому, що я розглядаю scope: {}визначення директиви як її API. Набагато простіше поглянути на визначення атрибуту області, щоб побачити, яка інформація потрібна директиві для належного функціонування, ніж це для пошуку функцій зв'язку та контролера для $emit'd подій, успадкованих функцій сфери чи функцій, що використовуються в інжектованих контролерах.


1

Моя думка:

Служби є кращим способом обміну поведінкою / даними через модулі / директиви / контролери. Директиви - це окремі речі, які можна вкладати чи ні. Контролери повинні дотримуватися можливості перегляду, наскільки це можливо, в ідеалі жодна бізнес-логіка не повинна закінчуватися там.

Тому:

Коли ви починаєте з'єднувати їх разом, отримуючи доступ до функцій батьківських областей, я думаю, ви ризикуєте занадто сильно з'єднати їх і зробити всю програму нечитабельною, а компоненти не використати багаторазово. Коли ви роз'єднуєте спільні дані або поведінку в сервісі, ви маєте перевагу повторно використовувати цілі директиви з різними даними / поведінкою, навіть визначаючи послугу, яку слід використовувати під час виконання. З чого полягає ін'єкція залежності.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.