【问题标题】:Angular 2 - Two way communication between componentsAngular 2 - 组件之间的双向通信
【发布时间】:2016-03-15 14:40:32
【问题描述】:

我有这段代码...这是我正在尝试构建的示例教程应用程序,它反映了开发人员的日常需求。 实际上,当用户在父组件上键入“fire”时,子组件会执行一个事件,该事件会向父组件发送单词“booom” - 这是一个示例,用于演示子组件之间使用 @Input 向父组件发送消息的通信和OnChanges。

现在,我正在尝试做一些不同的事情:当用户按下回车键 (keyCode == 13) 时,父母应该告诉孩子一个类似“目标锁定”的消息。有了这个,我们将有一个组件之间的 2 路通信场景。

什么是最好的方法?

子组件

import {Component, Input, OnChanges, EventEmitter,Output, Injectable} from 'angular2/core';
@Injectable()
@Component({
selector: 'child-component',
template: `<p>I'm the child component</p>
`
})
export class ChildComponent implements OnChanges { 
@Input() txt: string;
@Output() aim: EventEmitter<any> = new EventEmitter();
ngOnChanges(changes: {[propName: string]: SimpleChange}) {
    var t = changes['txt'].currentValue;
    if(t == 'fire') {
        console.log('Fire !!!');
        this.aim.emit("booom !!!");
    }
}
}

父组件

import {Component} from 'angular2/core';
import {ChildComponent} from './child.component'
@Component({
selector: 'parent-component',
directives : [ChildComponent]
template: `<p>I'm the parent component</p>
<input type="textbox" [(ngModel)]="theModel" (keydown)="arrow($event)">
<p>feedback: {{feedback}}</p>
<child-component txt="{{theModel}}" (aim)="feedback=$event"></child-component>
`
})
export class ParentComponent { 
theModel;
feedback;
arrow (evt){
    if(evt.keyCode ==13) {
        //Need to cause an event on the child - a message like "Target Locked"
    };
}
}

【问题讨论】:

  • 使用@Input()从父级与子级通信,@Output()从子级与父级通信,或使用服务。
  • “现在,我正在尝试做一些不同的事情:”——我看不出这里有什么不同。只需使用相同的输入和输出属性并发送不同的消息,或者添加另一组输入和输出属性。还可以查看Component Interaction cookbook
  • 父级使用 import 和选择器 合并子级 ny。因此,父母可以从孩子那里捕获(目标)事件。我的怀疑是要反其道而行之:子捕获父事件。请记住,孩子永远不会拥有父母的选择器。这就是为什么它真的不同。明白了吗?

标签: angular angular2-directives


【解决方案1】:

您可以提供EventEmitter 作为子组件的输入:

@Component({
  selector: 'child-component'
  (...)
})
export class ChildComponent {
  @Input()
  parentEventEmitter:EventEmitter;

  ngOnInit() {
    this.parentEventEmitter.subscribe((event) => {

    });
  }
}

然后孩子可以订阅它以得到通知...

这个EventEmitter 将在父组件中以这种方式提供:

<child-component
   [parentEventEmitter]="theEventEmitterFromTheParent">
</child-component>

【讨论】:

  • 无法实现:ngOnInit() { this.parentEventEmitter.subscribe((event) => { }); ---> this.parentEventEmitter.subscribe 不是 [ParentComponent 中的箭头中的函数 - 我将它放在 plunker 上 plnkr.co/edit/nqlCl6r5Ib64MCYJA5v9
【解决方案2】:

我的怀疑是要反其道而行之:子捕获父事件。请记住,孩子永远不会拥有父母的选择器。这就是它真正与众不同的原因。

我认为困惑在于您不需要事件这一事实。对于父→子通信,只需为子添加另一个输入属性。并将父属性绑定到它:

<child-component [anotherInputProperty]="someParentProperty" ...

然后,每当您更改父组件中someParentProperty 的值时,Angular 更改检测都会将新值传播给子组件:

if(evt.keyCode === 13) {
    // Need to cause an event on the child - a message like "Target Locked".
    // Just change the property value:
    this.someParentProperty = "some new value";
    // Angular will take care of propagating the new value to the child
};

如果你想让孩子在输入属性值改变时执行一些逻辑,在孩子中实现ngOnChanges()

如果问题是您不想每次都更改消息,那么您也可以

  • 使用a shared service with an Observable 并让孩子subscribe() 加入Observable,或者
  • 用随机值作为消息的前缀或后缀,并使用| 或其他您可以拆分的字符将其与消息分开,以便在孩子中轻松提取消息。

您还可以在共享服务中使用 Subject 而不是 Observable:请参阅 Parent and children communicate via a service

【讨论】:

  • ty,马克!!我会检查你的答案直到明天,如果适用,我不会忘记将你标记为答案。泰!
  • 您的解决方案正是我正在做的。老实说,它不是很优雅,但看起来它是唯一可以接受的 :( 例如,在我的真实项目中,我的父母中有一个 inputBox 。每次用户按下时,我都需要在我的子事件中引起反应(事件)箭头键。它可以向上和向下。所以,我以这种方式使用您的解决方案: if(event.keyCode ==40){ this.myChildProperty = 'down,' + Math.random(); } -如果我按下两次,随机将确保事件将被执行。但老实说我真的不喜欢这种解决方案。但既然它是唯一可以接受的,ok
  • @MarcoS.Junior,因为你一直提到“事件”这个词,听起来共享服务方法(使用 Observable 或 Subject)更适合你的用例,而不是输入属性。
【解决方案3】:

您需要实现事件发射器并在父组件中订阅它。您的发射器名称必须与绑定的值名称+'Change' 示例:如果您的值名称是“sum”,则您的事件需要是“sumChange”,这样您就可以从父级 liike [(sum)] = "value" 进行 2 路绑定。这是一个笨拙的例子:

https://plnkr.co/edit/efOGIJ0POh1XQeRZctSx?p=preview

【讨论】:

  • 听起来很有趣,莫希!我会在星期一学习这个,但我喜欢!
  • 基本上,您为父级设置了一个值。挑战是让父母在孩子身上引发事件。在我的示例中,我正在从孩子向父母提出一个事件。
  • 好吧,如果你注意到我改变了父母的价值,它反映在孩子身上,当我从孩子身上改变它时,它反映到父母身上。这是非常双向的通信。你想完成一些不同的事情吗?
猜你喜欢
  • 2021-04-13
  • 2021-03-02
  • 2018-02-08
  • 2017-01-01
  • 1970-01-01
  • 2016-12-03
  • 1970-01-01
  • 2017-12-24
  • 2014-05-24
相关资源
最近更新 更多