angular2兄弟组件通信

我有一个ListComponent。 在ListComponent中单击某个项目时,该项目的详细信息应显示在DetailComponent中。 两者同时在屏幕上,所以不涉及路由。

如何告诉DetailComponent ListComponent中的哪个项目被点击?

我已经考虑发布一个事件,直到父(AppComponent),并让父母用@Input在DetailComponent上设置selectedItem.id。 或者我可以使用可观察订阅的共享服务。


编辑:通过事件+ @Input设置选定的项目不会触发DetailComponent,但是,以防我需要执行额外的代码。 所以我不确定这是一个可接受的解决scheme。


但是这两种方法看起来都比Angular 1的做法要复杂得多,这个方法是通过$ rootScope。$ broadcast或$ scope。$ parent。$ broadcast来完成的。

Angular 2中的所有东西都是一个组件,我很惊讶没有关于组件通信的更多信息。

有没有另外一种更直接的方法来完成这个任务?

更新到rc.4:当试图在angular度2中的兄弟组件之间传递数据时,最简单的方法(angular.rc.4)是利用angular2的等级dependency injection并创build一个共享服务。

这将是服务:

import {Injectable} from '@angular/core'; @Injectable() export class SharedService { dataArray: string[] = []; insertData(data: string){ this.dataArray.unshift(data); } } 

现在,这里是PARENT组件

 import {Component} from '@angular/core'; import {SharedService} from './shared.service'; import {ChildComponent} from './child.component'; import {ChildSiblingComponent} from './child-sibling.component'; @Component({ selector: 'parent-component', template: ` <h1>Parent</h1> <div> <child-component></child-component> <child-sibling-component></child-sibling-component> </div> `, providers: [SharedService], directives: [ChildComponent, ChildSiblingComponent] }) export class parentComponent{ } 

和两个孩子

孩子1

 import {Component, OnInit} from '@angular/core'; import {SharedService} from './shared.service' @Component({ selector: 'child-component', template: ` <h1>I am a child</h1> <div> <ul *ngFor="#data in data"> <li>{{data}}</li> </ul> </div> ` }) export class ChildComponent implements OnInit{ data: string[] = []; constructor( private _sharedService: SharedService) { } ngOnInit():any { this.data = this._sharedService.dataArray; } } 

孩子2(兄弟姐妹)

 import {Component} from 'angular2/core'; import {SharedService} from './shared.service' @Component({ selector: 'child-sibling-component', template: ` <h1>I am a child</h1> <input type="text" [(ngModel)]="data"/> <button (click)="addData()"></button> ` }) export class ChildSiblingComponent{ data: string = 'Testing data'; constructor( private _sharedService: SharedService){} addData(){ this._sharedService.insertData(this.data); this.data = ''; } } 

现在:使用这种方法时需要注意的事项。

  1. 只在PARENT组件中包含共享服务的服务提供者,而不包括子对象。
  2. 您仍然必须包含构造函数并将该服务导入到子项中
  3. 这个答案最初是回答了一个早期的angular度2testing版本。 所有已经改变的都是导入语句,所以如果你偶然使用原始版本的话,你就需要更新。

如果有2个不同的组件(不是嵌套的组件,父\子\孙)我build议你这样做:

MissionService:

 import { Injectable } from '@angular/core'; import { Subject } from 'rxjs/Subject'; @Injectable() export class MissionService { // Observable string sources private missionAnnouncedSource = new Subject<string>(); private missionConfirmedSource = new Subject<string>(); // Observable string streams missionAnnounced$ = this.missionAnnouncedSource.asObservable(); missionConfirmed$ = this.missionConfirmedSource.asObservable(); // Service message commands announceMission(mission: string) { this.missionAnnouncedSource.next(mission); } confirmMission(astronaut: string) { this.missionConfirmedSource.next(astronaut); } } 

AstronautComponent:

 import { Component, Input, OnDestroy } from '@angular/core'; import { MissionService } from './mission.service'; import { Subscription } from 'rxjs/Subscription'; @Component({ selector: 'my-astronaut', template: ` <p> {{astronaut}}: <strong>{{mission}}</strong> <button (click)="confirm()" [disabled]="!announced || confirmed"> Confirm </button> </p> ` }) export class AstronautComponent implements OnDestroy { @Input() astronaut: string; mission = '<no mission announced>'; confirmed = false; announced = false; subscription: Subscription; constructor(private missionService: MissionService) { this.subscription = missionService.missionAnnounced$.subscribe( mission => { this.mission = mission; this.announced = true; this.confirmed = false; }); } confirm() { this.confirmed = true; this.missionService.confirmMission(this.astronaut); } ngOnDestroy() { // prevent memory leak when component destroyed this.subscription.unsubscribe(); } } 

来源: 家长和孩子通过服务进行交stream

这里有一个关于它的讨论。

https://github.com/angular/angular.io/issues/2663

亚历克斯·J的回答很好,但是到2017年7月,它不再适用于目前的Angular 4。

而这个链接将演示如何使用共享服务和可观察的兄弟姐妹之间的沟通。

https://embed.plnkr.co/P8xCEwSKgcOg07pwDrlO/

您需要设置组件之间的父子关系。 问题是你可能只需要在父组件的构造函数中注入子组件并将其存储在本地variables中。 相反,您应该通过使用@ViewChild属性声明@ViewChild声明父组件中的子组件。 这就是你的父组件应该是这样的:

 import { Component, ViewChild, AfterViewInit } from '@angular/core'; import { ListComponent } from './list.component'; import { DetailComponent } from './detail.component'; @Component({ selector: 'app-component', template: '<list-component></list-component><detail-component></detail-component>', directives: [ListComponent, DetailComponent] }) class AppComponent implements AfterViewInit { @ViewChild(ListComponent) listComponent:ListComponent; @ViewChild(DetailComponent) detailComponent: DetailComponent; ngAfterViewInit() { // afther this point the children are set, so you can use them this.detailComponent.doSomething(); } } 

https://angular.io/docs/ts/latest/api/core/index/ViewChild-var.html

https://angular.io/docs/ts/latest/cookbook/component-communication.html#parent-to-view-child

请注意,只有在调用ngAfterViewInit生命周期钩子后,子组件的构造函数才会在父组件的构造函数中可用。 为了抓住这个钩子,在父类中实现AfterViewInit接口的方式与使用OnInit方法相同。

但是,在这个博客注释中还有其他的属性声明: http : //blog.mgechev.com/2016/01/23/angular2-viewchildren-contentchildren-difference-viewproviders/

这不是你真正想要的,但肯定会帮助你

我很惊讶没有更多关于组件通信的信息 <=> 请看angualr2

对于兄弟组件的沟通,我build议去sharedService 。 也有其他选项可用。

 import {Component,bind} from 'angular2/core'; import {bootstrap} from 'angular2/platform/browser'; import {HTTP_PROVIDERS} from 'angular2/http'; import {NameService} from 'src/nameService'; import {TheContent} from 'src/content'; import {Navbar} from 'src/nav'; @Component({ selector: 'app', directives: [TheContent,Navbar], providers: [NameService], template: '<navbar></navbar><thecontent></thecontent>' }) export class App { constructor() { console.log('App started'); } } bootstrap(App,[]); 

请参阅上方的链接了解更多代码。

编辑:这是一个非常小的演示。 您已经提到您已经使用sharedService进行了尝试。 所以请考虑由angualr2本教程欲了解更多信息。

我一直通过一个绑定将父类的setter方法传递给其中的一个子元素,并使用子元素中的数据调用该方法,这意味着父元素将被更新,然后可以使用新数据更新其第二个子元素。 它确实需要绑定“this”或者使用箭头函数。

这样做的好处是,孩子们不需要彼此联系,因为他们不需要特定的共享服务。

我不完全确定这是最好的做法,听到别人对此的看法会很有意思。