问题描述
我有一个父组件,它观察子组件的 Output
事件发射器 (topicsChanged)
。
父组件:
import {
ChangeDetectionStrategy,Component,EventEmitter,Input,OnInit,Output
} from "@angular/core";
import { Language } from "../language";
import { Templatetopic } from "../template-topic";
@Component({
selector: "at-main-topics",templateUrl: "./main-topics.component.html",changeDetection: ChangeDetectionStrategy.OnPush
})
export class MainTopicsComponent implements OnInit {
@input() templates: string[] = [];
@input() templatetopics: Templatetopic[] = [];
@input() languages: Language[] = [];
@Output() templatetopicChanged = new EventEmitter<Templatetopic>();
constructor() {}
ngOnInit(): void {}
get availableTemplatetopics(): Templatetopic[] {
return this.templates
.map(x => +x)
.map(template => {
const existingTopic = this.templatetopics.find(
x => x.template === template
);
return (
existingTopic ||
{ //observer will disappear for this empty created object.
template: template,topics: []
}
);
});
}
onTopicsChanged(templatetopic: Templatetopic) {
// This will not be triggered for 3rd template which is created in availableTemplatetopics getter,because it doesn't exist in initial data (templatetopics)
this.templatetopicChanged.emit(templatetopic);
}
}
<at-template-topic *ngFor="let templatetopic of availableTemplatetopics"
[templatetopic]="templatetopic"
[languages]="languages"
(topicsChanged)="onTopicsChanged($event)">
</at-template-topic>
在一个奇怪的情况下,这个事件发射器失去了它的父组件的观察者。那就是 - 在子组件中我打开一个对话框。在打开对话框之前,如果我检查发射器,观察者在那里,但是一旦对话框关闭,观察者就消失了。
子组件:
import { Component,Output } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { Language } from '../language';
import { Templatetopic } from '../template-topic';
import { Topic } from '../topic';
import { TranslationDialogModel } from '../translation-dialog.model';
import { TranslationDialogComponent } from '../translation-dialog/translation-dialog.component';
@Component({
selector: 'at-template-topic',templateUrl: './template-topic.component.html'
})
export class TemplatetopicComponent implements OnInit {
@input() templatetopic: Templatetopic;
@input() languages: Language[] = [];
@Output() topicsChanged = new EventEmitter<Templatetopic>();
private dialogTitle: string = 'lorem ipsum'
constructor(
private dialog: MatDialog
) { }
ngOnInit(): void {
}
onCreatetopic(): void {
this.openDialog();
}
onEditTopic(topic: Topic): void {
this.openDialog(topic);
}
private openDialog(topic?: Topic): void {
// this.topicsChanged always has observer at this point
const dialogRef = this.dialog.open(TranslationDialogComponent,{
data: {
pageTitle: this.dialogTitle,availableLanguages: this.languages,translations: topic?.translations
} as TranslationDialogModel
});
dialogRef
.beforeClosed()
.subscribe(translations => {
if (translations) {
if (topic) {
topic.translations = translations;
topic.title = translations[0].title;
} else {
this.templatetopic.topics.push({ translations,title: translations[0].title })
}
// When called via onCreatetopic method for a category which was created as an empty placeholder,this.topicsChanged has lost it's observer. However if category had initial data,then observer is still there.
this.topicsChanged.emit(this.templatetopic);
}
})
}
}
对话框中没有任何可疑之处,它只是返回一些数据,仅此而已。这以某种方式连接到父组件中的 getter get availableTemplatetopics
,从中创建子组件列表。在 getter 中有一个代表每个子组件的模板列表,这些子组件要么从现有数据填充,要么创建一个空的占位符。问题在于空的占位符对象。
片段:
get availableTemplatetopics(): Templatetopic[] {
return this.templates
.map(x => +x)
.map(template => {
const existingTopic = this.templatetopics.find(
x => x.template === template
);
return (
existingTopic ||
{ //observer will disappear for this empty created object.
template: template,topics: []
}
);
});
}
我发现我可以通过将 getter 逻辑上移一级来解决所有这些问题,但我仍然想了解这种奇怪的行为。观察者怎么会就这样消失,它是如何连接到吸气剂的?
完整代码的 Stackblitz:https://stackblitz.com/edit/angular-kjewu7?file=src/app/main-topics/main-topics.component.ts
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)