2015-04-27 1 views
0

У меня есть директива, которая абстрагирует меню. Выбор пункта меню должен быть уведомлен его родительскому контроллеру, чтобы он мог выполнять требуемые действия. Есть несколько способов добиться этого.AngularJS, уведомление об изменении данных от директивы к его родительскому контроллеру

  1. Передача переменной области действия от контроллера к директиве и наблюдение за изменением этой переменной. В пределах директивы измените эту переменную, чтобы указать параметр выбора.

  2. Передайте метод обратного вызова от контроллера к директиве. Вызовите обратный вызов из директивы после изменения.

  3. Обратите внимание на изменения в контроллере, используя $ объем. $, И уведомляет из директивы, используя сферу. $ Испускают

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

UPDATE:

После прочтения предложения и мысли, я взял Вариант 2 для следующих причин:

  1. Это совершенно очевидно, глядя в HTML о зависимости

    <menu save="onSave()" filterByDate="filterByDate(date)"></menu> 
    
  2. Единичное тестирование очень явное и рассказать об API (интерфейсе) директивы

+1

Оба варианта 2 и 3 в порядке. С вариантом 2 ваша зависимость явно. – Chandermani

+0

Я бы выбрал вариант 2. Вариант 3 тоже будет прекрасен, но мне не нравится событие, как сказал Чандермани, это путь менее явный. – tanou

ответ

1

Мне лично не нравится использовать функцию watch \ emit \ on, если у меня тоже нет. Это не всегда очевидно, глядя на какой-то код elses, где он установлен. Это может привести к коду спагетти. Если у вас есть обратный звонок, я считаю, что прямая связь более очевидна для глаз и легче найти. Это связано с хорошо названными свойствами и т. Д. В конце концов, это вопрос личного \ командного вкуса.

0

Я рекомендую использовать модифицированную версию 1. Но вместо передачи переменной, введи сервис, где вам нужно.

Сервис может выглядеть примерно так:

yourApp.factory('SelectedMenu', 
     function() { 
      //set a default or just initialize it 
      var menuItem = { 
       id: 1, 
       code:"x" 
      }; 
      return { 
       getId: function() { return menuItem.id; }, 
       getCode: function() { return menuItem.code;}, 
       setId: function(newId){menuItem.id = newId}, 
       setCode: function(newCode){menuItem.code=newCode;}, 
      }; 
     } 
    ); 

В директиве (ы), которые контролирующая поведение создать часы:

$scope.$watch(
         function() { 
          //should be idempotent! can execute multiple times per $digest cycle when a change is detected 
          // (good compromise for not polluting $rootScope) 
          return SelectedMenu.getId(); 
         }, 
         function(newValue) { 
          //do your thing... 
         } 
        ); 

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

SelectedMenu.setId(someones.id); 

Это самое чистое решение, с которым я столкнулся. Если вы хотите, вы можете абстрагировать использование еще больше с другой службой, если объект данных является более сложным.

Смежные вопросы