我是一位经验丰富的程序员,但对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
答案 0 :(得分:0)
您不必深入挖掘。这是一个简单的修复。发射器称为emitter
。因此,您必须绑定到该名称。尝试以下
<app-child (emitter)="parentFunction($event)"></app-child>
或者,如果您希望绑定到submitButtonClicked
,则应该将发射器命名为submitButtonClicked
。
@Output() submitButtonClicked = new EventEmitter<string>();
如果您想了解有关事件发射器的更多信息,可以看一下source。它是Rxjs Subject的简单扩展。因此,在创建事件发射器时,实际上是一个可观察到的事件,其名称用@Output()
装饰器修饰。因此,要从发射器获取值,需要对其进行订阅。发射器名称是正在订阅的可观察对象的名称。