角度 2 同级组件通信

2022-08-30 04:38:43

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

如何告诉 DetailComponent ListComponent 中的哪一项被点击了?

我考虑过将事件发送到父级(AppComponent),并让父级在 DetailComponent 上设置 selectedItem.id,并@Input。或者,我可以使用具有可观察订阅的共享服务。


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


但这两种方法似乎都比Angular 1的做事方式复杂得多,后者是通过$rootScope.$broadcast或$scope.$parent.$broadcast。

由于Angular 2中的所有内容都是组件,我很惊讶没有更多关于组件通信的信息。

有没有另一种/更直接的方法来实现这一点?


答案 1

更新到 rc.4:当尝试在angular 2中的同级组件之间传递数据时,现在最简单的方法(angular.rc.4)是利用angular2的分层依赖注入并创建共享服务。

以下是服务:

import {Injectable} from '@angular/core';

@Injectable()
export class SharedService {
    dataArray: string[] = [];

    insertData(data: string){
        this.dataArray.unshift(data);
    }
}

现在,这里是父组件

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 2 beta版本回答的。所有已更改的都是 import 语句,因此,如果您偶然使用了原始版本,则只需更新即可。

答案 2

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

使命服务:

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

}

宇航员组成:

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();
  }
}

来源:家长和子女通过服务进行通信