从动态创建的子组件向父组件发送事件
Emit event from dynamically created child component to parent component
我有一个滑块,其中包含动态创建的项目 - 这些是子组件。
滑块的 ng-container 所在的父模板:
<div id="slider-wrapper">
<ng-container appSliderForm *ngFor="let question of questionsInSlider"
[questionTest]="question" (onRemove)="removeQuestion($event)">
</ng-container>
</div>
这些子组件由 appSliderForm 指令创建:
@Directive({
selector: '[appSliderForm]'
})
export class FormSliderDirective implements OnInit {
@Input()
questionTest: QuestionInSlider;
constructor(private resolver: ComponentFactoryResolver, private container: ViewContainerRef) {}
ngOnInit(): void {
const factory = this.resolver.resolveComponentFactory<TestQuestionInSliderComponent>(TestQuestionInSliderComponent);
const component = this.container.createComponent(factory);
component.instance.questionTest = this.questionTest;
component.instance.ref = component;
}
}
在我的子组件中,我有一个 remove 函数,用于将其自身从滑块中移除。
@Component({
selector: 'app-test-question-in-slider',
templateUrl: './test-question-in-slider.component.html',
styleUrls: ['./test-question-in-slider.component.less']
})
export class TestQuestionInSliderComponent {
questionTest: QuestionInSlider;
ref: any;
@Output() public onRemove = new EventEmitter<QuestionInSlider>();
constructor(private builderService: FormBuilderService) {}
/**
* Chosen question from slider will be displayed.
*/
choose(): void {
this.questionTest.chosen = true;
this.builderService.handlerQuestionFromSlider(this.questionTest);
}
remove(): void {
this.onRemove.emit(this.questionTest);
this.ref.destroy();
}
isChosen() {
return {'chosen': this.questionTest.chosen};
}
getBorderTopStyle() {
return {'border-top': `4px solid ${this.questionTest.color}`};
}
}
当通过单击子组件模板中的删除图标调用此删除函数时,我想发出事件以告知父组件根据其进行其他操作,但是函数 未调用父组件中的 removeQuestion。
你能告诉我为什么不调用这个 removeQuestion 函数吗?
removeQuestion(question: QuestionInSlider) {
console.log(question);
}
更新
我在 chrome 浏览器中调试了它,我发现我的 onRemove EventEmitter 对象在他的观察者数组中没有任何值 属性 当在 onRemove 对象上调用 emit 函数时。
this.onRemove.emit(this.questionTest);
问题是 FormSliderDirective
没有 onRemove
事件。为了使您的代码正常工作,您需要将事件添加到指令并将其订阅到内部组件的事件。因此,无论何时触发内部事件,它都会传播到外部。
这是一个示例,说明如何将其添加到指令中:
@Directive({
selector: '[appSliderForm]'
})
export class FormSliderDirective implements OnInit {
@Input() questionTest: QuestionInSlider;
@Output() public onRemove = new EventEmitter<QuestionInSlider>();
constructor(private resolver: ComponentFactoryResolver, private container: ViewContainerRef) {}
ngOnInit(): void {
const factory = this.resolver.resolveComponentFactory<TestQuestionInSliderComponent>(TestQuestionInSliderComponent);
const component = this.container.createComponent(factory);
component.instance.questionTest = this.questionTest;
component.instance.onRemove.subscribe(this.onRemove); // this connects the component event to the directive event
component.instance.ref = component;
}
}
当应用@AlesD 的解决方案后发生相同的错误时,也许它会对您有所帮助:
ERROR TypeError: Cannot read property 'subscribe' of undefined
解决方法对我有用:
component.instance.onRemove = this.onRemove;
我有一个滑块,其中包含动态创建的项目 - 这些是子组件。
滑块的 ng-container 所在的父模板:
<div id="slider-wrapper">
<ng-container appSliderForm *ngFor="let question of questionsInSlider"
[questionTest]="question" (onRemove)="removeQuestion($event)">
</ng-container>
</div>
这些子组件由 appSliderForm 指令创建:
@Directive({
selector: '[appSliderForm]'
})
export class FormSliderDirective implements OnInit {
@Input()
questionTest: QuestionInSlider;
constructor(private resolver: ComponentFactoryResolver, private container: ViewContainerRef) {}
ngOnInit(): void {
const factory = this.resolver.resolveComponentFactory<TestQuestionInSliderComponent>(TestQuestionInSliderComponent);
const component = this.container.createComponent(factory);
component.instance.questionTest = this.questionTest;
component.instance.ref = component;
}
}
在我的子组件中,我有一个 remove 函数,用于将其自身从滑块中移除。
@Component({
selector: 'app-test-question-in-slider',
templateUrl: './test-question-in-slider.component.html',
styleUrls: ['./test-question-in-slider.component.less']
})
export class TestQuestionInSliderComponent {
questionTest: QuestionInSlider;
ref: any;
@Output() public onRemove = new EventEmitter<QuestionInSlider>();
constructor(private builderService: FormBuilderService) {}
/**
* Chosen question from slider will be displayed.
*/
choose(): void {
this.questionTest.chosen = true;
this.builderService.handlerQuestionFromSlider(this.questionTest);
}
remove(): void {
this.onRemove.emit(this.questionTest);
this.ref.destroy();
}
isChosen() {
return {'chosen': this.questionTest.chosen};
}
getBorderTopStyle() {
return {'border-top': `4px solid ${this.questionTest.color}`};
}
}
当通过单击子组件模板中的删除图标调用此删除函数时,我想发出事件以告知父组件根据其进行其他操作,但是函数 未调用父组件中的 removeQuestion。
你能告诉我为什么不调用这个 removeQuestion 函数吗?
removeQuestion(question: QuestionInSlider) {
console.log(question);
}
更新
我在 chrome 浏览器中调试了它,我发现我的 onRemove EventEmitter 对象在他的观察者数组中没有任何值 属性 当在 onRemove 对象上调用 emit 函数时。
this.onRemove.emit(this.questionTest);
问题是 FormSliderDirective
没有 onRemove
事件。为了使您的代码正常工作,您需要将事件添加到指令并将其订阅到内部组件的事件。因此,无论何时触发内部事件,它都会传播到外部。
这是一个示例,说明如何将其添加到指令中:
@Directive({
selector: '[appSliderForm]'
})
export class FormSliderDirective implements OnInit {
@Input() questionTest: QuestionInSlider;
@Output() public onRemove = new EventEmitter<QuestionInSlider>();
constructor(private resolver: ComponentFactoryResolver, private container: ViewContainerRef) {}
ngOnInit(): void {
const factory = this.resolver.resolveComponentFactory<TestQuestionInSliderComponent>(TestQuestionInSliderComponent);
const component = this.container.createComponent(factory);
component.instance.questionTest = this.questionTest;
component.instance.onRemove.subscribe(this.onRemove); // this connects the component event to the directive event
component.instance.ref = component;
}
}
当应用@AlesD 的解决方案后发生相同的错误时,也许它会对您有所帮助:
ERROR TypeError: Cannot read property 'subscribe' of undefined
解决方法对我有用:
component.instance.onRemove = this.onRemove;