0

I've got a child component in my Angular 5 application that does two-way binding, and the binding is working properly. I'm having a bit of an issue with knowing about the change though in the parent controller. In the parent I use the child component like so:

<app-lab-hazard-classification-question-group
        primaryQuestion="Does the lab contain mechanical tools?"
        [(primaryValue)]="lab.hazardClassificationDetails.mechanicalExists"></app-lab-hazard-classification-question-group>

The lab variable is an @Input() to the parent control. When I evaluate the value of lab.hazardClassificationDetails.mechanicalExists it's properly being set by the child component. I need to know though, in the parent control, when that value gets modified. Because the lab variable itself doesn't change, the ngOnChanges method isn't actually called.

Do I have to add a (change) item to the child controller and explicitly bind that to be notified of the change? I was hoping for a more generic way as I have around 10 of these child elements, and I don't care "what" value it changed to, just that it did in fact change.

The child component's .ts file has this:

@Input() primaryValue: boolean;
@Output() primaryValueChange = new EventEmitter();

onPrimaryChanged(): void {
    this.primaryValueChange.emit(this.primaryValue);
}

and the HTML has something like this:

<select class="form-control" id="primary" name="primary" required
        [(ngModel)]="primaryValue"
        (change)="onPrimaryChanged()">
            <option [ngValue]="null || undefined">-- Select --</option>
            <option [ngValue]="true">Yes</option>
            <option [ngValue]="false">No</option>
        </select>
Gargoyle
  • 9,590
  • 16
  • 80
  • 145

1 Answers1

1

A good approach could be to emit an event with EventEmitter from the child component to the parent component in case of value change.

gr4viton
  • 1,434
  • 1
  • 8
  • 21
  • So you're saying to add the `(change)` item to each of the items in the parent's HTML? – Gargoyle Oct 23 '18 at 16:40
  • @Balázs Takács you meant ``EventEmitter``? I think this idea is good, create custom event with ``@Output`` and inform parent whenever some value changes. – Buczkowski Oct 23 '18 at 16:58
  • @Buczkowski Thank you for the catch. I meant EventEmitter. – gr4viton Oct 23 '18 at 17:01
  • @Gargoyle You mentioned that you do not care what is the new value after the change. By creating an EventEmitter you do not have to pass the new value to the parent component. It is enough to just notify it with a simple emit. – gr4viton Oct 23 '18 at 17:03
  • 1
    I do have emitters for each child question that passes the value to support the two-way binding. I just added an extra `change` emitter that they all call as well so I added a `(change)="onSomethingChanged()"` to each of the HTML blocks. – Gargoyle Oct 23 '18 at 17:25