Angular 1.5,从父控制器调用组件中的函数

TkN*_*Neo 23 angularjs

Angular 1.5组件可以轻松地从组件创建回调父级的回调.有没有办法可以从父控制器中的函数调用组件中的函数?

让我们说我的组件叫做task-runner,下面是父容器中的HTML.

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

 <button type="button" ng-click="doSomethingInParent()">ParentToChildButton</button>
Run Code Online (Sandbox Code Playgroud)

那个傻瓜就在这里.我希望在单击ParentToChildButton时,函数doSomethingInParent()调用组件中的remotefunc.

ada*_*101 19

几种不同的方式:

  1. 使用双向绑定(scope:{myattr:'='})将对象作为属性传递给task-item-header指令,该指令随后可以添加一个函数供父控制器调用.
  2. 设置一个属性,该属性具有单向绑定(scope:{myattr:'@'}),然后attrs.$observe更改为触发操作,或双向绑定(scope:{myattr:'='}),然后$scope.$watch更改为触发操作.
  3. 让指令引发一个event(scope:{raiseLoaded:'&onLoaded'}),它传递一个表示远程控制对象的对象,并在其上触发所需的操作.要引发事件,你会raiseLoaded({remoteControl: remoteControlObj})在指令中调用类似的内容,然后听取事件,<task-item-header on-loaded="setRemote(remoteControl)">假设你setRemote()的父控制器上有一个方法.

更新我刚刚意识到你的问题是针对更新版本的AngularJS,所以我不确定我的答案是否仍然适用.我暂时把它留在这里,但是如果你发现它没用,我可以删除它.

  • @TkNeo,我修改了你的plunkr,就像我在#3中描述的那样:http://plnkr.co/edit/vRVZB9EhhZd4sYTGoPvC?p = info (4认同)

rdr*_*drw 14

我以前需要这样的东西所以我想我会分享我是如何解决这个问题的.

与OP类似,我需要从父组件中自由触发子组件中的方法.我希望能够在不使用$ onChanges生命周期钩子的情况下自由地/单独地在父级中触发此方法.

相反,我创建了一个通知注册机制,允许子组件在加载时向父项"注册"一个方法.然后,此方法可以由$ onChanges周期之外的父项自由触发.

我创建了一个codepen来演示这个.可以轻松扩展它以处理来自父级的与数据更改无关的不同类型的通知.

的index.html

<div ng-app="tester">
  <parent></parent>
</div>
Run Code Online (Sandbox Code Playgroud)

的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);
  };
};
Run Code Online (Sandbox Code Playgroud)

}

对于与@ adam0101的#3 类似的答案,请参阅codepen.

  • 关于这个答案,可以通过在父控制器中声明 `ctrl.onXxEvt = {}` 来简化;然后在父模板的子组件锚点处声明 `onXxEvt="$ctrl.onXxEvt"`;然后在孩子的控制器的 `$onInit` 中声明 `ctrl.onXxEvt.handler = xxEvtHander`。现在你可以在父控制器中调用 `ctrl.onXxEvt.handler`,它会在子控制器中调用 `xxEvtHander`。这避免了显式注册方法。 (2认同)