在 AngularJS 组件中从父级到子级传递事件 [英] Communicating Events from Parent to Child in AngularJS Components

查看:27
本文介绍了在 AngularJS 组件中从父级到子级传递事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我正在处理的新项目中,我开始使用组件而不是指令.

in the new project I'm working on I've started using the components instead of directives.

但是,我遇到了一个问题,我找不到具体的标准方法来做到这一点.

however, I've encountered an issue where I cannot find a concrete standard way to do it.

将事件从子级通知给父级很容易,您可以在下面的我的 plunkr 上找到它,但是从父级到子级通知事件的正确方法是什么?

It's easy to notify an event from child to parent, you can find it on my plunkr below, but what's the correct way to notify a event from parent to child?

Angular2 似乎通过使用这样的东西来解决这个问题:https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-local-var但我不认为有可能像 #timer 的例子那样定义一个指向子组件的指针"

Angular2 seems to solve this issue by using something like this: https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-local-var But I don't tink there's a possibilty to define a "pointer" to the child component like the example did with #timer

为了保持到 Angular2 的可能轻松转换,我想避免:

In order to mantain a possible easy conversion to Angular2 I want to avoid:

  • 事件发射(从作用域发射和广播)
  • 使用来自孩子的要求(然后向父母添加回调......丑陋)
  • 使用单向绑定,将作用域注入到子对象中,然后观察"这个属性.更丑

示例代码:

var app = angular.module('plunker', []);

app.controller('RootController', function() {
});

app.component('parentComponent', {
  template: `
    <h3>Parent component</h3>
    <a class="btn btn-default btn-sm" ng-click="$ctrl.click()">Notify Child</a>
    <span data-ng-bind="$ctrl.childMessage"></span>
    <child-component on-change="$ctrl.notifiedFromChild(count)"></child-component>
  `,
  controller: function() {
    var ctrl = this;
    ctrl.notifiedFromChild = function(count){
      ctrl.childMessage = "From child " + count;
    }
    ctrl.click = function(){
    }
  },
  bindings: {
  }
});

app.component('childComponent', {
  template: `
    <h4>Child component</h4>
    <a class="btn btn-default btn-sm" ng-click="$ctrl.click()">Notify Parent</a>
  `,
  controller: function() {
    var ctrl = this;
    ctrl.counter = 0;
    ctrl.click = function(){
        ctrl.onChange({ count: ++ctrl.counter });
    }
  },
  bindings: {
    onChange: '&'
  }
});

您可以在此处找到示例:

You can find an example here:

http://plnkr.co/edit/SCK8XlYoYCRceCP7q2Rn?p=preview

这是我创建的一个可能的解决方案

This is a possible solution I created

http://plnkr.co/edit/OfANmt4zLyPG2SZyVNLr?p=preview

孩子需要父母的地方,然后孩子设置对孩子的父母引用......现在父母可以使用孩子......丑陋但它就像上面的angular2示例

where the child requires the parent, and then child sets a parent reference to the child... now parent can use the child... ugly but it's like angular2 example above

推荐答案

在 AngularJS 组件中从父级到子级通信事件

使用表达式绑定发布指令 $API

要允许父组件向子组件传递事件,请让子组件发布 API:

Communicating Events from Parent to Child in AngularJS Components

Publish Directive $API Using Expression Binding

To allow parent components to communicate events to a child component, have the child publish an API:

<grid-component grid-on-init="$ctrl.gridApi=$API; $ctrl.someFn($API)">
</grid-component>    

JS

app.component('gridComponent', {
  //Create API binding
  bindings: {gridOnInit: "&"},
  template: `
    <h4>Grid component</h4>
    <p> Save count = {{$ctrl.count}}</p>
  `,
  controller: function() {
    var ctrl = this;
    this.$onInit = function() {
        ctrl.count = 0;
        ctrl.api = {};
        //Publish save function
        ctrl.api.save = save;
        //Invoke Expression with $API as local
        ctrl.gridOnInit({$API: ctrl.api});
    };
    function save(){
      console.log("saved!");
      ctrl.count++;
    }
  }
});

以上示例调用由 grid-on-init 属性定义的 Angular 表达式,其 API 公开为 $API.这种方法的优点是父组件可以通过使用 Angular 表达式将函数传递给子组件来响应子组件的初始化.

The above example invokes the Angular Expression defined by the grid-on-init attribute with its API exposed as $API. The advantage to this approach is that the parent can react to child initialization by passing a function to the child component with the Angular Expression.

来自文档:

isolate"作用域对象哈希定义了一组从指令元素上的属性派生的局部作用域属性.这些本地属性对于模板的别名值非常有用.对象哈希中的键映射到隔离作用域上的属性名称;这些值定义了属性如何通过匹配指令元素上的属性绑定到父作用域:

The 'isolate' scope object hash defines a set of local scope properties derived from attributes on the directive's element. These local properties are useful for aliasing values for templates. The keys in the object hash map to the name of the property on the isolate scope; the values define how the property is bound to the parent scope, via matching attributes on the directive's element:

  • &&attr - 提供了一种在父作用域的上下文中执行表达式的方法.如果未指定属性名称,则假定属性名称与本地名称相同.给定 <my-component my-attr="count = count + value"> 和隔离范围定义范围: { localFn:'&myAttr' },隔离作用域属性 localFn 将指向 count = count + value 表达式 的函数包装器.通常希望通过表达式将数据从隔离作用域传递到父作用域.这可以通过将局部变量名称和值的映射传递到表达式包装器 fn 中来完成.例如,如果表达式是 increment($amount) 那么我们可以通过将 localFn 调用为 localFn({$amount: 22}) 来指定金额值.
  • & or &attr - provides a way to execute an expression in the context of the parent scope. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given <my-component my-attr="count = count + value"> and the isolate scope definition scope: { localFn:'&myAttr' }, the isolate scope property localFn will point to a function wrapper for the count = count + value expression. Often it's desirable to pass data from the isolated scope via an expression to the parent scope. This can be done by passing a map of local variable names and values into the expression wrapper fn. For example, if the expression is increment($amount) then we can specify the amount value by calling the localFn as localFn({$amount: 22}).

-- AngularJS 综合指令 API -- 范围

作为惯例,我建议在局部变量前加上 $ 前缀,以将它们与父变量区分开来.

As a convention, I recommend prefixing local variables with $ to distinguish them from parent variables.

注意:为了轻松过渡到 Angular 2+,请避免使用双向 = 绑定.而是使用单向 < 绑定和表达式 & 绑定.有关详细信息,请参阅 AngularJS 开发人员指南 - 了解组件.

NOTE: To ease the transition to Angular 2+, avoid the use of bi-directional = binding. Instead use one-way < binding and expression & binding. For more information, see AngularJS Developer Guide - Understanding Components.

要允许父组件向子组件传递事件,请让子组件发布 API:

To allow parent components to communicate events to a child component, have the child publish an API:

<grid-component api="$ctrl.gridApi"></grid-component>

在上面的示例中,grid-component 使用绑定将其 API 发布到使用 api 属性的父作用域上.

In the above example, the grid-component uses bindings to publish its API onto the parent scope using the api attribute.

app.component('gridComponent', {
  //Create API binding
  bindings: {api: "="},
  template: `
    <h4>Grid component</h4>
    <p> Save count = {{$ctrl.count}}</p>
  `,
  controller: function() {
    var ctrl = this;
    this.$onInit = function() {
        ctrl.count = 0;
        ctrl.api = {};
        //Publish save function
        ctrl.api.save = save;
    };
    function save(){
      console.log("saved!");
      ctrl.count++;
    }
  }
});

然后父组件可以使用发布的API调用子save函数:

Then the parent component can invoke the child save function using the published API:

ctrl.click = function(){
  console.log("Search clicked");
  ctrl.gridApi.save();
}

PLNKR 演示.

这篇关于在 AngularJS 组件中从父级到子级传递事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆