Angular 9: родительская функция не вызывается на EventEmitter.emit от дочернего - PullRequest
0 голосов
/ 07 апреля 2020

Я опытный программист, но довольно плохо знаком с Angular.

Я только что прошел хорошее руководство по Angular и попытался попрактиковаться в передаче значений из дочернего компонента в его вызывающую функцию ( parent).

Каким-то образом, несмотря на то, что я уменьшаю сложность до минимума, моя родительская функция даже не вызывается, что я связал с эмиттером.

После обслуживания приложения (ng serve) Я вижу только следующее в консоли:

child.component.ts:17 submitButtonClicked called

Я вошел в emit-Call, используя код VS и отладчик для Chrome:

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

После двух шагов я приземлился в Субъекте. js и увидел, что его переменная-член "наблюдатели" пуста. Я ожидаю, что массив наблюдателей содержит как минимум ParentComponent. См. Subject. js код в конце страницы.

Я имею в виду, это действительно просто, но я просто не могу определить, где я ошибся: - /

В чем может быть причина и решение?

Буду очень признателен за вашу помощь!

Parent (parent.component. html)

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

Parent (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 (child.component. html)

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

Child (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");
  }

}

Root (app.component. html)

<app-parent></app-parent>

Root (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';
}

Root Модуль (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 { }

Тема. 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 - версия):

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 голосов
/ 07 апреля 2020

Вам не нужно копать вглубь. Это простое исправление. Излучатель называется emitter. Таким образом, вы должны связать это имя. Попробуйте следующее

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

Или, если вы хотите sh связать с submitButtonClicked, тогда эмитент должен называться submitButtonClicked.

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

Если вы wi sh чтобы узнать больше об источнике событий, вы можете посмотреть его источник . Это простое расширение Rx js Subject . Поэтому, когда создается источник событий, он на самом деле является наблюдаемой, называемой именем, украшенным декоратором @Output(). Таким образом, чтобы получить значения от эмиттера, необходимо подписаться на него. А имя эмитента - это имя наблюдаемой, на которую подписывается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...