Angular 2 - 组件之间的双向通信

时间:2016-03-15 14:40:33

标签: angular angular2-directives

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

现在,我正在尝试做不同的事情:当用户按下回车键(keyCode == 13)时,父母应该向孩子讲述向孩子发送“Target Locked”这样的消息。有了这个,我们将有一个组件之间的双向通信的场景。

最好的方法是什么?

child.component

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 !!!");
    }
}
}

parent.component

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"
    };
}
}

3 个答案:

答案 0 :(得分:3)

  

我怀疑是要采取相反的方式:儿童捕捉父母的事件。请记住,孩子永远不会拥有父母的选择。这就是为什么它真的不同。

我认为混乱是因为你不需要一个事件。对于父→子通信,只需向子项添加另一个输入属性。并将父属性绑定到它:

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

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

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

答案 1 :(得分:2)

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

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

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

    });
  }
}

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

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

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

答案 2 :(得分:1)

您需要实现事件发射器并在父组件中订阅它。您的发射器名称必须与绑定值名称匹配+'更改'示例:如果您的值名称为“sum”,则您的事件需要为“sumChange”,这样您就可以从父级别[(sum)] = "value"进行双向绑定。这是一个很好的例子:

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