javascriptangulareventemittertwo-way-bindingsubcomponent

EventEmitter from Subcomponent not working


I want to have a two-way-binding from a parent-component to a sub-component. This already works well in one of my components which looks as follows (I emitted some css-classes and other not relevant parts):

parent habit-show.component.html:

{{habit.label}}
<app-habit-edit [(habit)]="habit" ></app-habit-edit>

subcomponent habit-edit.component.html:

<input id="habitName" name="label" [(ngModel)]="habit.label" required/>

subcomponent habit-edit.component.ts:

@Input()
private habit: Habit ;

@Output()
habitChange = new EventEmitter<Habit>();

This works as expected: I can see the habit.label in the parent-component and when I change the value in the input it automatically changes too. Now this is the part of the component that isn't working:

parent habit-edit.component.html:

 {{habit.goalActive}}
 <app-checkbox [(mappedModel)]="habit.goalActive" ></app-checkbox>

subcomponent checkbox.component.html:

 {{mappedModel}}
 <input name="checkbox-input" [(ngModel)]="mappedModel" type="checkbox">

subcomponent checkbox.component.ts:

 @Input()
 private mappedModel: boolean;

 @Output()
 mappedModelChange = new EventEmitter<boolean>();

Now in this case, the value in the parent-component doesn't update and I have no idea why, since I did basically the same. The value in the child-component does update correctly.

One thing worth noting might be, that the child component from the first (working) example is the parent in the second example -> that shouldn't be a problem though, should it?

Also the updating of the parent container works when I add a button whenever I press that button (it still doesn't update from the checkbox value though):

parent habit-edit.component.html:

 {{habit.goalActive}}
 <app-checkbox [(mappedModel)]="habit.goalActive" ></app-checkbox>

subcomponent checkbox.component.html:

 {{mappedModel}}
 <input name="checkbox-input" [(ngModel)]="mappedModel" type="checkbox">
 <button (click)="test()">Test</button>

subcomponent checkbox.component.ts:

 @Input()
 private mappedModel: boolean;

 @Output()
 mappedModelChange = new EventEmitter<boolean>();

 test(){
    this.mappedModel = !this.mappedModel;
   this.mappedModelChange.emit(this.mappedModel);
 }

And if I add the test-function to the input itself, nothing at all happens, whenever I press it (not even the mappedModel in the child component updates then)

<label (click)="test()">{{mappedModel}}
   <input name="checkbox-input" [(ngModel)]="mappedModel" type="checkbox">

The problem seems to be that I can't properly bind habit.goalActive with the eventemitter from the subcomponent (maybe because it is the property of an object an not the whole object?) I'm still confused though, since this is no problem with [(ngModel)] on inputs


Solution

  • in your input in child component add change event and call test fuction and remove the ngModel

    <input name="checkbox-input"  [ngModel]="mappedModel" (change)="test()" type="checkbox">