【问题标题】:Angular 10 - Event Emmiter is not working - Sharing information between child and parent componentAngular 10 - Eventemitter 不工作 - 在子组件和父组件之间共享信息
【发布时间】:2021-03-02 02:26:41
【问题描述】:

我在 Angular 中有这个父子组件,我正在尝试将一个对象从子组件传递给父组件,以便更新父对象数组中的值。我一直在关注角度文档示例,但似乎它没有将新对象发送到 paren 组件,但无论是控制台还是 VSC 终端都没有显示任何错误。

这是我遵循的角度指南:https://angular.io/guide/inputs-outputs#sending-data-to-a-parent-component

父视图:

<h1>Customers list</h1>

<mat-list>
  <a mat-list-item *ngFor="let customr of customers" [routerLink]="[customr.id, {name: customr.name}]">{{ customr.name }}</a>
</mat-list>


<router-outlet (newItemEvent)="addItem($event)"></router-outlet>

Parent controller:

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

@Component({
  selector: 'app-customer-list',
  templateUrl: './customer-list.component.html',
  styleUrls: ['./customer-list.component.scss']
})
export class CustomerListComponent implements OnInit {


  // list = [
  //   { id: 1, name: 'John Smith' },
  //   { id: 2, name: 'Anna Highland' },
  //   { id: 3, name: 'Emilie Poiret' }
  // ];

  customers: Array<Object> = [
    {
      id: 1,
      name: 'John Smith'
    },
    {
      id: 2,
      name: 'Anna Highland'
    },
    {
      id: 3,
      name: 'Emilie Poiret'
    }
  ];

  addItem(customer){
    console.log(`add customer ${customer}`);
  }

  constructor() { }

  updateCustomer(data){
    console.log(data);
  }

  ngOnInit(): void {
  }
}

子视图:

<p>{{ name }}</p>


<form [formGroup]="formGroup" (ngSubmit)='addNewItem()'>

  <mat-form-field>
    <mat-label>Customer name:</mat-label>
    <input matInput name="customerName" formControlName="customerName">
  </mat-form-field>

  <button mat-raised-button type="submit">Action</button>

</form>

儿童控制器:

import { ActivatedRoute, Params } from '@angular/router';
import { Component, Input, OnInit } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-customer-detail',
  templateUrl: './customer-detail.component.html',
  styleUrls: ['./customer-detail.component.scss']
})
export class CustomerDetailComponent implements OnInit {

  // https://angular.io/guide/inputs-outputs#sending-data-to-a-parent-component
  @Output() newItemEvent = new EventEmitter<object>();

  formGroup: FormGroup;
  id: string;
  name: string;

  addNewItem(){
  //  console.log(`emit runs ${value}`);
    let id: any = this.id;
    let name = this.formGroup.value.customerName;
    console.log(`id: ${this.id} i name: ${this.formGroup.value.customerName}`);
    let customer = {
      'id': this.id,
      'name': this.formGroup.value.customerName
    };
    console.warn(customer);
    this.newItemEvent.emit(customer);
  }


  constructor(private fb: FormBuilder, private routes: ActivatedRoute) { }

  ngOnInit(): void {

    this.routes.params.subscribe(
      (params: Params) => {
        this.id = params.id;
        this.name = params.name;
      }
    );

    console.log(`ngOnInit ${this.name}`);

    this.buildForm();

  }

  private buildForm(): void {
    console.log(`buildForm ${this.name}`);
    this.formGroup = this.fb.group({
      customerName: [this.name, Validators.required]
    });

  }

  public saveEdit() {
    console.log(`Save edit`);
    return { 'id': this.formGroup.value.customerId, 'name': this.formGroup.value.customerName };
  }

}

当我单击按钮时,我看到了它正在执行的 addNewItem 的 console.log,但是在父组件函数上的 addItem 上我没有看到 console.log,目标是传递 id 和客户的名字,所以我可以用客户的新信息更新客户数组

【问题讨论】:

  • &lt;router-outlet&gt; 无法接受发出的事件。如果你仔细阅读本教程,你会发现事件被父组件的选择器捕获。
  • 是的,我看到了,但是 它是我必须将子组件放置在父组件中的元素。在我的 app.component.html 上,我只有在整个应用程序和路由器插座上始终相同的标头组件。如果这不可能,我有什么机会?
  • 对 - 所以你试图在 Angular 上即兴创作 - 我明白了,但是 Angular 太复杂了,无法在时尚中破解。但是既然你在进步,你应该看看data management using services来帮你解决你的问题。这是大多数企业应用程序的编写方式。
  • 服务似乎更有可能工作我会用这个感谢链接????????????????

标签: javascript angular angular-event-emitter


【解决方案1】:

路由器出口组件只是角度路由器使用的一个标记,以便知道将要为不同路由渲染的组件的放置位置。在这个组件上放置一个事件监听器不会产生任何结果,因为它不是真正的路由组件。

您可以使用service 或执行以下操作:

export class AppComponent {
  @ViewChild(RouterOutlet) outlet: RouterOutlet;

  constructor(router: Router) {
    router.events.pipe(filter(e => e instanceof NavigationEnd)).subscribe(() => {
      const c = this.outlet.component;
    });
  }
}
  1. 查询路由器出口组件

  2. 监听导航结束事件,以便在路由组件发生变化时得到通知。

  3. 获取当前组件实例并对其进行操作。在您的情况下,您将拥有一个事件发射器,您可以订阅该事件。

在这里,我假设这将在 AppComponent 中使用,并且我没有取消订阅,但是如果您打算在具有命名插座的内部组件中使用它,并且该组件可能会在某个时候被销毁,请制作确保您取消订阅流以防止内存泄漏。

【讨论】:

    【解决方案2】:

    这不起作用的主要原因是@user1 提到&lt;router-outlet&gt; 不能像组件那样接收参数。此外,他关于创建服务以在组件之间共享所有信息的建议是最合适的,也是 Angular 文档推荐的:https://angular.io/tutorial/toh-pt4

    【讨论】:

      猜你喜欢
      • 2018-05-22
      • 2023-03-22
      • 2020-07-20
      • 2021-01-04
      • 2016-12-03
      • 2021-12-23
      • 2016-12-17
      • 2017-10-03
      • 2019-09-25
      相关资源
      最近更新 更多