I have a slider in which are dynamically created items - these are child components.
Parent template where is ng-container for slider:
<div id="slider-wrapper">
<ng-container appSliderForm *ngFor="let question of questionsInSlider"
[questionTest]="question" (onRemove)="removeQuestion($event)">
</ng-container>
</div>
These child components are created by appSliderForm directive:
@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;
}
}
In my child component, I have a remove function for removing itself from a slider.
@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}`};
}
}
When this remove function is called by clicking on remove icon in child component template then I would like to emit the event to give a know to parent component to make other operations according to, but the function removeQuestion in parent component is not called.
Could you advise me please why is not called this removeQuestion function?
removeQuestion(question: QuestionInSlider) {
console.log(question);
}
UPDATE
I've debugged it in the chrome browser and I saw that my onRemove EventEmitter object hadn't any values in his the observers array property when the emit function was called on the onRemove object.
this.onRemove.emit(this.questionTest);
The problem is that the FormSliderDirective
does not have an onRemove
event. For your code to work you need to add the event to the directive and subscribe it to the event of the internal component. So whenever the internal event fires it will be propagated to the outside.
Here is a sample how you can add this to your directive:
@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;
}
}
Perhaps it will help you when the same error happens after applying the solution from @AlesD:
ERROR TypeError: Cannot read property 'subscribe' of undefined
The workaround works for me:
component.instance.onRemove = this.onRemove;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With