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

Angular 1.5, вызов функции в компоненте из родительского контроллера

Angular 1.5 компоненты легко позволяют создать обратный вызов родительского элемента. Есть ли способ, который я могу вызвать функцию в компоненте из функции родительского контроллера?

Допустим, что мой компонент называется task-runner, а ниже - HTML для него в родительском контейнере.

<task-runner taskcategogyid=5></task-runner>

 <button type="button" ng-click="doSomethingInParent()">ParentToChildButton</button>

Здесь plunkr . Я хочу, чтобы при нажатии ParentToChildButton функция doSomethingInParent() вызывает remotefunc в компоненте.

4b9b3361

Ответ 1

Несколько способов:

  • Передайте объект как атрибут с двусторонней привязкой (scope:{myattr:'='}) к директиве заголовка элемента-объекта, которую директива может затем добавить функцию для вызова родительского контроллера.
  • Установите атрибут, который имеет одностороннюю привязку (scope:{myattr:'@'}) на нем, а затем attrs.$observe изменяет его, чтобы вызвать действие, или двустороннюю привязку (scope:{myattr:'='}), а затем $scope.$watch изменяется на чтобы вызвать действие.
  • Попросите директиву поднять событие (scope:{raiseLoaded:'&onLoaded'}), которое передает объект, представляющий объект удаленного управления, с помощью метода, который вызывает действие, которое вы хотите. Чтобы поднять событие, вы вызываете в директиве что-то вроде raiseLoaded({remoteControl: remoteControlObj}), а затем для прослушивания события используйте <task-item-header on-loaded="setRemote(remoteControl)">, если у вас есть метод setRemote() на вашем родительском контроллере.

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

Ответ 2

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

Подобно OP, мне нужно было свободно триггерные методы в дочерних компонентах из родительского компонента. Я хотел иметь возможность запускать этот метод в родительском режиме свободно/отдельно без использования привязки жизненного цикла $onChanges.

Вместо этого я создал механизм регистрации уведомлений, чтобы позволить дочернему компоненту "регистрировать" метод с родителем при его загрузке. Этот метод затем может свободно запускаться родителем вне цикла $onChanges.

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

Index.html

<div ng-app="tester">
  <parent></parent>
</div>

Script.js

angular.module('tester', []);

angular.module('tester').component('parent', {
  controller: parentController,
  template: `
    <div class="tester-style">
      <button ng-click="$ctrl.notifyChild()">Notify child</button>
      <child parent-to-child-notification-registration="$ctrl.childComponentNotificationRegistration(handler)">
    </div>
  `
});

function parentController() {
  let childComponentEventHandler = null;

  this.$onInit = function() {
    this.value = 0;
  };

  this.childComponentNotificationRegistration = function(handler) {
    childComponentEventHandler = handler;
    console.log('Child component registered.');
  };

  this.notifyChild = function() {
    if (childComponentEventHandler) {
      childComponentEventHandler(this.value++);
    }
  };
}

angular.module('tester').component('child', {
  bindings: {
    parentToChildNotificationRegistration: '&',
  },
  controller: childController,
  template: `
    <div class="tester-style">
      <h4>Child Component</h4>
    </div>
  `
});

function childController() {
  this.$onInit = function() {
    this.parentToChildNotificationRegistration({
      handler: this.processParentNotification
    });
  };

  this.processParentNotification= function(parentValue) {
    console.log('Parent triggered child notification handler!!!');
    console.log('Value passed to handler:', parentValue);
  };
};

}

Также для чего-то похожего на @adam0101 # 3 ответ см. codepen.