Angular 2 兄弟组件通信 [英] Angular 2 Sibling Component Communication

查看:31
本文介绍了Angular 2 兄弟组件通信的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

<小时>

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

<小时>

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

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

是否有另一种/更直接的方法来实现这一目标?

解决方案

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

这里是服务:

从'@angular/core'导入{Injectable};@Injectable()导出类 SharedService {数据数组:字符串[] = [];插入数据(数据:字符串){this.dataArray.unshift(data);}}

现在,这里是 PARENT 组件

从'@angular/core'导入{Component};从'./shared.service'导入{SharedService};从 './child.component' 导入 {ChildComponent};从'./child-sibling.component'导入{ChildSiblingComponent};@成分({选择器:'父组件',模板:`<h1>父</h1><div><子组件></子组件><child-sibling-component></child-sibling-component>

`,提供者:[共享服务],指令:[ChildComponent, ChildSiblingComponent]})导出类 parentComponent{}

和它的两个孩子

孩子 1

import {Component, OnInit} from '@angular/core';从./shared.service"导入 {SharedService}@成分({选择器:'子组件',模板:`<h1>我是个孩子</h1><div><ul *ngFor="#data in data"><li>{{data}}</li>

`})导出类 ChildComponent 实现 OnInit{数据:字符串[] = [];构造函数(私人 _sharedService: SharedService) { }ngOnInit():any {this.data = this._sharedService.dataArray;}}

child 2 (这是兄弟姐妹)

从'angular2/core'导入{Component};从./shared.service"导入 {SharedService}@成分({选择器:'子兄弟组件',模板:`<h1>我是个孩子</h1><input type="text" [(ngModel)]="data"/><按钮(点击)="addData()"></button>`})导出类 ChildSiblingComponent{数据:string = '测试数据';构造函数(私有_sharedService:SharedService){}添加数据(){this._sharedService.insertData(this.data);this.data = '';}}

现在:使用此方法时需要注意的事项.

  1. 仅在 PARENT 组件中包含共享服务的服务提供者,而不包含子组件.
  2. 您仍然必须包含构造函数并在子项中导入服务
  3. 此答案最初是针对早期的 angular 2 测试版回答的.不过,所有已更改的是导入语句,因此如果您偶然使用原始版本,则只需更新这些语句.

I have a ListComponent. When an item is clicked in ListComponent, the details of that item should be shown in DetailComponent. Both are on the screen at the same time, so there's no routing involved.

How do I tell DetailComponent what item in ListComponent was clicked?

I've considered emitting an event up to the parent (AppComponent), and have the parent set the selectedItem.id on DetailComponent with an @Input. Or I could use a shared service with observable subscriptions.


EDIT: Setting the selected item via event + @Input doesn't trigger the DetailComponent, though, in case I were to need to execute additional code. So I'm not sure this is an acceptable solution.


But both of these methods seem far more complex than the Angular 1 way of doing things which was either through $rootScope.$broadcast or $scope.$parent.$broadcast.

With everything in Angular 2 being a component, I'm surprised there's not more information out there about component communication.

Is there another/more straightforward way to accomplish this?

解决方案

Updated to rc.4: When trying to get data passed between sibling components in angular 2, The simplest way right now (angular.rc.4) is to take advantage of angular2's hierarchal dependency injection and create a shared service.

Here would be the service:

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

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

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

Now, here would be the PARENT component

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{

} 

and its two children

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

child 2 (It's sibling)

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 = '';
    }
}

NOW: Things to take note of when using this method.

  1. Only include the service provider for the shared service in the PARENT component and NOT the children.
  2. You still have to include constructors and import the service in the children
  3. This answer was originally answered for an early angular 2 beta version. All that has changed though are the import statements, so that is all you need to update if you used the original version by chance.

这篇关于Angular 2 兄弟组件通信的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆