【问题标题】:How to communicate from button click on parent to child components using angular2?如何使用angular2从按钮单击父组件到子组件进行通信?
【发布时间】:2017-12-20 02:57:33
【问题描述】:

我有一个父 AppComponent 和另一个名为“ChildComponent”的组件。它们都共享一个名为“appState”的服务,该服务被注入两者(我使用的是https://github.com/AngularClass/angular-starter,app.service.ts 类在这里是https://github.com/AngularClass/angular-starter/blob/master/src/app/app.service.ts,这是我所指的appState)。

ChildComponent 有自己的属性“mylist”,它是一个对象数组,设置为等于 this.appState.mylist。

@Component(...)
export class ChildComponent {
  mylist = any;
  constructor(@Inject(AppState) appState) {
    public appState = appState;
    mylist = appState.state.mylist;
  }
}

我有一个显示 {{mylist}} 的 ChildComponent 模板

ParentComponent 有一个模板,该模板有一个“添加我”按钮,其唯一功能是添加到 this.appState.mylist。

我的问题是,当我点击父组件上的“添加我”按钮时,我在函数中记录了 this.appState.mylist。

@Component(...)
export class AppComponent {
  constructor() {
    public appState = appState;
    appState.mylist = [];
  }

  addMe() {
    this.appState.state.mylist.push({"itemName":"Something"});
    console.log(this.appState.mylist) // this outputs correctly and I see mylist growing
  }
}

我了解了 eventEmitters 如何发出事件来更新父级,但就我而言,我想更新 AppComponent 模板中的一个组件。怎么了?如何使 child.component.html 中的“mylist”显示正确的数据?

我看到的所有文档似乎都在谈论从子到父通信的 EventEmitters,这似乎对我不起作用,因为我试图从我的父 AppComponent 到子 ChildComponent 进行通信。

问题plunkr: https://plnkr.co/edit/xaE905r4xNZcVJzWQwsr?p=preview

【问题讨论】:

    标签: angular


    【解决方案1】:

    更新: OP 设置服务的方式,问题是子组件没有得到更新的appState.mylist。因此,我提供的解决方案是使用SubjectObservable 通知子组件更改并通过subscription. 拉入新数据

    child.components.ts:

    mylist: any;
    
    constructor(private appState: AppState){
      this.appState.dataString$.subscribe(
        data => {
          this.mylist = data.mylist; 
        });
    }
    

    请查看plunker demo 获取service.ts 代码。

    原帖:

    由于您有父子关系,您可以像使用数据绑定一样轻松地将mylist 传递给子组件。 <child-component [mylist]="mylist"></child-component>

    在子组件中,您可以使用@Input() 将父组件传递的数据绑定到子组件中的mylist 变量。

    如果你还想使用共享服务,那么你就在正确的轨道上,只需要清理父子组件中的代码,如下所示:

    父母:

    constructor(private appState: AppState){
        this.appState.mylist = [];
      }
    
      addMe() {
        this.appState.mylist.push({"itemName":"Something"});
    
        console.log(this.appState.mylist) // this outputs correctly and I see mylist growing
    
        this.mylistFromParent.push({"itemName":"Something"}); 
      }
    

    孩子:

    mylist: any;
    
      constructor(private appState: AppState){
      this.mylist = this.appState.mylist;
    }
    

    我创建了这个demo 来说明这两种情况。

    希望这会有所帮助!

    【讨论】:

    • 这有帮助!但是您可以尝试使用我在链接中引用的 appService 实现吗?当我执行我描述的方法时,它会锁定整个界面并崩溃。
    • 您使用共享服务描述的方法*
    • 我确实使用appState (appService) 进行共享服务,它称为AppState,就像在您的代码中一样。唯一的区别是文件名,在我的演示中称为shared.service.ts,很可能在您的项目中名为app.service.ts。关于“锁定整个界面并崩溃”,如果您可以分享您的代码,那将很有帮助:)
    • 创建的 plunkr 显示了我从您的 plunkr 中遇到的问题。我复制了我帖子中引用的“app.service.ts”来替换您 shared.service.ts 的内容。请注意当我尝试点击添加按钮时它是如何不起作用的。如果您注释掉使用 appState 的行,则第二种方法有效。 plnkr.co/edit/xaE905r4xNZcVJzWQwsr?p=preview。如果可能的话,我宁愿让第一种方法起作用。请看一下,让我知道发生了什么事。
    • plunkr 中有一个myListCopy 的拼写错误,这让我有一段时间完全走错了路。但我发现一旦组件实例化为AppState,它们就不会得到更新。所以,在修复它的过程中,我学到了一些新东西,使用Subjectobservable 来通知所有组件共享服务的更改。我已经清楚地标记了新行,以便您轻松找到它们。这是 plunkr 链接:plnkr.co/edit/JncNuE63jwQsYgImK2ba
    猜你喜欢
    • 1970-01-01
    • 2017-07-15
    • 2018-04-08
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 2021-06-11
    • 2017-05-19
    • 2018-12-24
    相关资源
    最近更新 更多