【问题标题】:Emit event (or alternative) from grandchild component Angular 9从孙子组件Angular 9发出事件(或替代)
【发布时间】:2020-05-14 06:49:37
【问题描述】:

我的结构类似于 AngularJS 应用程序 -> Angular 组件(主)-> 子组件 -> 孙子组件。我的孙子组件上发生了单击事件,我想向 AngularJS 应用程序发出事件。我已经在我的 AngularJS 应用程序中添加了监听器,如果我从主组件发出事件,那么它可以工作,但不能来自孙子。将每个级别的事件链接起来可能是一个解决方案,但看起来并没有优化,因为可能有很多这样的事件。我在一些线程上读到,从服务中发出事件不是一个好习惯(我仍然尝试过,但无论如何都没有工作)。有没有其他办法?

【问题讨论】:

  • 我有相同的应用程序结构。我使用 Angular 可降级服务或 AngularJs 可升级服务在我所有的孙子和 AngularJs 实体之间进行通信。当然,我们正在将它们全部转换为 Angular 并最终弃用 AngularJ。如果我理解正确,如果你想继续这条路,也许可以问一个更技术性的问题,为什么这对你不起作用?
  • 我们也在升级的路上,但一步一步做,所以需要同时整合两者。我的架构师希望保持组件独立于服务端点,因此客户端应该在需要时调用服务并将数据提供给组件。链接事件应该可以工作,但那将是我会选择的最后一个选择。我是说服务中的 emit() 对我不起作用。它不调用客户的侦听器。您能否详细说明您所说的可升级/可降级服务?

标签: angular events angular-services emit


【解决方案1】:

看看 RxJS 主题。 每当点击事件发生时,在 grandChild 中执行 subject.next(); 然后在 AngularJS 应用程序中订阅它。

【讨论】:

  • 好的。让我试一试。我会带着结果回来。谢谢。
  • 您能否详细说明 AngularJS 将如何订阅?我的意思是它将如何获得服务参考来进行订阅?
  • 首先在服务中,将属性定义为 Subject 然后在另一个属性中获取其 .asObservable() ,然后在方法上执行您的主要 Subject 属性的 .next() ,然后在您的目的地组件,获取您在服务中将其设置为asObservable 的属性并订阅它。如果您需要示例,请告诉我。
  • 你可以在每个组件中使用依赖注入来获取你的服务
  • 感谢您的回复。似乎我在评论中的问题不清楚。我的 AngularJS 应用程序是独立的,我在其中注入了这个 Angular 组件。我的问题是我的 AngularJS 应用程序将如何订阅组件服务中的 observable?尽管如此,我已经实现了你的 RxJS 推荐并且它正在工作。唯一的事情是我需要使用父组件作为 AngularJS 和孙子之间的桥梁,但我可以跳过所有其他中间层。如果我可以在 AngularJS 中订阅 observable 的组件服务,我也可以消除父组件的依赖。
【解决方案2】:

请尝试下面给出的代码

// --------------------------------------
// app.component.html

<div>
  <span>Master to Child </span><input type="textbox" [(ngModel)]='master'>
</div>

<app-child [childToMaster]=master (childToParent)="childToParent($event)"></app-child>

<app-grand-child [childToMaster]=master (childToParent)="childToParent($event)"></app-grand-child>

// --------------------------------------
// app.component.ts

import { Component, Output,EventEmitter } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  //passing values from parent to child
  master : String="send from parent";
  
  //Getting value from child
  childToParent(name){
    this.master=name;
  }

}

// --------------------------------------
// app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';

import { AppComponent } from './app.component';
import { AppChildComponent } from './app-child.component';
import { AppGrandChildComponent } from './app-grand-child.component';


@NgModule({
  imports:      [ BrowserModule, FormsModule ],
  declarations: [ AppComponent, AppChildComponent, AppGrandChildComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

// --------------------------------------
// app-grand-child.component.ts

import { Component, Input, Output,EventEmitter } from '@angular/core';

@Component({
  selector: 'app-grand-child',
  template: `
    <input type="textbox" [(ngModel)]='masterName'> 
    <button (click)="sendToParent(masterName)" >sendToParent</button>
    <div>{{masterName}}</div>
  `
})
export class AppGrandChildComponent {
  //getting value from parent to child
  @Input('childToMaster') masterName: string;

  @Output() childToParent = new EventEmitter<String>();

  

  sendToParent(name){
    //alert("hello");
    this.childToParent.emit(name);
  }
}



// --------------------------------------
// app-child.component.ts

import { Component, Input, Output,EventEmitter } from '@angular/core';

@Component({
  selector: 'app-child',
  template: `
    <input type="textbox" [(ngModel)]='masterName'> 
    <button (click)="sendToParent(masterName)" >sendToParent</button>
    <div>{{masterName}}</div>
  `
})
export class AppChildComponent {
  //getting value from parent to child
  @Input('childToMaster') masterName: string;

  @Output() childToParent = new EventEmitter<String>();

  

  sendToParent(name){
    //alert("hello");
    this.childToParent.emit(name);
  }
}

【讨论】:

  • 感谢 Pooja。这是我在问题中提到的链接,它也可以工作,但我正在寻找更好的选择(如果可用),因为在我的情况下会有很多这样的事件。如果没有,我将采用此解决方案并将其标记为答案。
  • 好的,另一种方式是“与服务共享数据”
猜你喜欢
  • 2018-09-30
  • 2019-01-10
  • 2023-01-07
  • 1970-01-01
  • 2019-07-20
  • 2019-11-23
相关资源
最近更新 更多