角度9:未在子事件

时间:2020-04-06 21:02:02

标签: angular

我是一位经验丰富的程序员,但对Angular还是很陌生。

我刚刚阅读了一篇不错的Angular教程,并尝试了将值从子组件传递到其调用者(父)的实践。

尽管如此,尽管我将复杂性降低到最低程度,但我的父函数甚至没有被调用,而我已经绑定到了发射器。

在投放应用程序(ng serve)后,我在控制台中仅看到以下内容:

child.component.ts:17 submitButtonClicked called

我使用适用于Chrome的VS代码和调试器进入了emit-Call:

submitButtonClicked() {
  console.log("submitButtonClicked called");
  this.emitter.emit("Test");
}

经过两步,我进入了Subject.js,发现其成员变量“ observers”为空。 我希望观察者数组至少包含ParentComponent。请参见页面末尾的Subject.js代码。

我的意思是,这确实很简单,但我只是无法确定哪里出了错:-/

是什么原因和解决方案?

非常感谢您的帮助!

父级(parent.component.html)

 <p>parent works!</p>
 <app-child (submitButtonClicked)="parentFunction($event)"></app-child>

父母(parent.component.ts)

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

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

  constructor() { }

  ngOnInit(): void {
  }

  parentFunction (str: string) {
    console.log("parentFunction called, str = " + str);
  }
}

孩子(child.component.html)

<p>child works!</p>
<button type="submit" (click)="submitButtonClicked()">Submit</button>

孩子(child.component.ts)

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

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

  @Output() emitter = new EventEmitter<string>();
  constructor() { }

  ngOnInit(): void {
  }

  submitButtonClicked() {
    console.log("submitButtonClicked called");
    this.emitter.emit("Test");
  }

}

根(app.component.html)

<app-parent></app-parent>

根(app.component.ts)

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  title = 'My App';
}

根模块(app.module.ts)

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

import { AppComponent } from './app.component';
import { ParentComponent } from './parent/parent.component';
import { ChildComponent } from './child/child.component';


@NgModule({
  declarations: [
    AppComponent,
    ParentComponent,
    ChildComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Subject.js

export class Subject extends Observable {
    constructor() {
        super();
        this.observers = [];
        this.closed = false;
        this.isStopped = false;
        this.hasError = false;
        this.thrownError = null;
    }
    [rxSubscriberSymbol]() {
        return new SubjectSubscriber(this);
    }
    lift(operator) {
        const subject = new AnonymousSubject(this, this);
        subject.operator = operator;
        return subject;
    }
    next(value) {
        if (this.closed) {
            throw new ObjectUnsubscribedError();
        }
        if (!this.isStopped) {
            const { observers } = this;
            const len = observers.length;
            const copy = observers.slice();
            for (let i = 0; i < len; i++) {
                copy[i].next(value);
            }
        }
    }
 ... // Snippet ends here

我的Angular环境(ng --version):

Angular CLI: 9.0.7
Node: 12.16.1
OS: win32 x64
Angular: 9.0.7
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes
Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.900.7
@angular-devkit/build-angular     0.900.7
@angular-devkit/build-optimizer   0.900.7
@angular-devkit/build-webpack     0.900.7
@angular-devkit/core              9.0.7
@angular-devkit/schematics        9.0.7
@ngtools/webpack                  9.0.7
@schematics/angular               9.0.7
@schematics/update                0.900.7
rxjs                              6.5.5
typescript                        3.7.5
webpack                           4.41.2

1 个答案:

答案 0 :(得分:0)

您不必深入挖掘。这是一个简单的修复。发射器称为emitter。因此,您必须绑定到该名称。尝试以下

<app-child (emitter)="parentFunction($event)"></app-child>

或者,如果您希望绑定到submitButtonClicked,则应该将发射器命名为submitButtonClicked

@Output() submitButtonClicked = new EventEmitter<string>();

如果您想了解有关事件发射器的更多信息,可以看一下source。它是Rxjs Subject的简单扩展。因此,在创建事件发射器时,实际上是一个可观察到的事件,其名称用@Output()装饰器修饰。因此,要从发射器获取值,需要对其进行订阅。发射器名称是正在订阅的可观察对象的名称。