【问题标题】:How to pass data to single @Input from multiple components in Angular 2?如何从Angular 2中的多个组件将数据传递给单个@Input?
【发布时间】:2017-01-16 18:51:48
【问题描述】:

我正在开发一个以不同模块分隔的大型 Angular 2 应用程序,如下所示:

  • 应用程序模块:
    • user.module
    • supplier.module
    • shared.module

从我的共享模块中,我为应用程序中的所有模态调用了一个 Bootstrap 4 模态组件,我使用 @Input 装饰器通过模态配置对象对其进行自定义。这是我的模态组件 .ts 的样子:

modal.component.ts:

export class ModalComponent {

    constructor() { }

    public modalMethods = new ModalActionMethods();

    @Input() modalConf: ModalModel;

}

然后从模态模板内部,我引用 modalConf 对象,如下所示:

modal.template.html:

<div class="bg-modal-container" [hidden]="!modalConf.isOpen">

最后,当我在需要它的任何组件的视图中使用它时,我将数据传递给模态组件:

whatever.component.html:

<modal [modalConf]="modalOptions"></modal>

modalOptions 引用了在我的whatever.component 的主类中定义的对象。

whatever.component.ts

export class WhatevertComponent {
    private modalOptions = {
        isOpen: false,
        title: "Some Modal Title"
        // etc.
    }
}

到目前为止一切顺利。

现在,对于我的用户模块,因为我知道我将在多个组件中大量使用我的模态组件,所以我想做一些不同的事情,因为这个模块根据路线为不同的组件提供服务:

users.routing.ts:

const routes: Routes = [
    {
        path: '', component: UsersComponent,
        children: [
            { path: 'creation', component: UserCreationComponent },
            { path: 'management', component: UserManagementComponent }
        ]
    }
];

问题:

我想做的是将我的模态组件插入到我的主用户组件中(将 modalOptions 对象放置在它的主类中,并将模态选择器放在视图中,与上面的 whatever-component 相同) ,但也能够以某种方式从其他子组件中修改模态配置,例如创建、管理等,以便我可以在我的模态中显示相关的子组件数据。 我要避免的是在将要使用/操作它的每个子组件中插入(并为其创建单独的 modalConf 对象)我的模态组件。

最好的方法是什么?我愿意接受建议。

【问题讨论】:

  • 我从这个问题的解释是您正在尝试实现跨组件通信,为此您可以使用服务类作为中间体来使用事件发射器传递数据
  • 如果我没记错的话,这听起来像是 Rxjs 商店的完美用例。 github.com/ngrx/store
  • 你好,拉胡尔·辛格。感谢您的反馈意见。我已经将服务用作我的模态组件的一部分,并定义了一个独特的 getDefaultConf() 方法。您认为使用 currentConf 的两个新的 setter 和 getter 方法扩展此服务并将我的 @Input 装饰器绑定到 getter 会成功吗?

标签: javascript angular typescript


【解决方案1】:

所以...在 Jaime 和 Rahul 对我最初的问题的回答之后,我找到了解决问题的潜在方法。按照他们的建议,我在服务中使用了 RxJS Observables 来允许 whatever-component 的子组件进行交互和通信。我将在下面发布我的实现,希望这可以帮助其他有同样问题的人。

首先,我用两种新方法扩展了我的模态服务,用于设置和获取模态配置。

modal.service.ts

import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { Observable } from 'rxjs/Observable';
import { ModalModel } from '../../models/modal.model';

@Injectable()
export class ModalService {

    private currentConf: ModalModel;

    private confSubject: Subject<ModalModel> = new Subject<ModalModel>();

    public getDefaultConf() {
        return {
            // some default conf
        };
    }

    public setCurrentConf(conf: ModalModel): void {
        this.currentConf = conf;
        this.confSubject.next(conf);
    }

    public getCurrentConf(): Observable<ModalModel> {
        return this.confSubject.asObservable();
    }

}

然后我将模态组件调用从我的子组件移到了我的主组件(whatever-component)中。在这个组件中,我导入了 modal 服务,使用默认配置初始化了 modal,并在 ngInit 上订阅了该服务的 get 方法。

whatever.component.ts

import { ModalService } from '../../shared/modal/modal.service';
// ...

export class WhateverComponent {

    public modalOptions: any = this._modalService.getDefaultConf();

    ngOnInit() {
        this._modalService.getCurrentConf().subscribe( (conf: any) => {
            this.modalOptions = conf;
        });
    }
}

最后,我从子组件内部导入了模态服务,并在需要更新模态配置时使用其set 方法:

this._modalService.setCurrentConf(childCompModalConfig);

我不确定是否需要取消订阅 ngDestroy 上的服务,或者 RxJS 是否会自动处理。

如果有人有更好的方法并希望分享,请不要犹豫。 谢谢!

【讨论】:

    猜你喜欢
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    • 2017-01-08
    • 2017-08-30
    • 2017-06-15
    • 2017-09-23
    相关资源
    最近更新 更多