Angular communication between parent and child components

808 views Asked by At

I have a case where I have a parent component and 2 child component (selection components based on ng-select) The idea is that when I select and item in the first ng-select, the same should be disabled in the 2nd. And vice versa.

In the parent I am using @ViewChildren to query the component and the set disabled input property

In the children I am emitting the information I need in the parent when I choose and item in the ng-select

In this method I am then finding the correct child component and setting the disabled input property

const connectionSelector = this.connectionSelectors.find(connectionSelector => connectionSelector.source == false);
connectionSelector.disabledConnection = this.selectedSourceConnection;

In the child component I have ngOnChanges method to check for the changes but the disabledConnection property does not get updated

It only works when I make a page load I am both emitting the changes to the parent on OnInit and when I change the item in the ng-select so the changes are emitted to the parent

Parent view:

<sc-connection-selector [default]="false" [source]="true" [quick]="false"
      [selectedConnection]="selectedSourceConnection"
      [disabledConnectionId]="disabledTargetConnectionId"
      (dataToEmit)="onValueChanged($event)">
</sc-connection-selector>

Child:

<ng-select [items]="connections" bindLabel="userName"
    [placeholder]="'general.select-placeholder' | translate " 
    (change)="onConnectionChange()" 
    groupBy="type"
    dropdownPosition="bottom" 
    [(ngModel)]="selectedConnection">
    <ng-template ng-optgroup-tmp let-item="item">
      <b>{{item.type || 'Unnamed group'}}</b>
    </ng-template>
  </ng-select>

What am I missing here ?

-Jani

1

There are 1 answers

10
Moshezauros On BEST ANSWER

Edit:

You are updating the value on the child component, no on the parent, OnChanges will trigger if

data-bound property of a directive changes

this means, that when the value on the parent component changes, it will trigger OnChanges on the child component.

For you to get the desired behavior, you should move the relevant section (where you update the disabled property) from the OnChanges function to the setter of disabledConnectionId, so every time that (disabledConnectionId) changes, you update the dropdown, here is the relevant code:

private currentDisabledConnectionId: Number;
@Input()
set disabledConnectionId(val: number) {
  if (this.currentDisabledConnectionId !== val) {
    this.currentDisabledConnectionId = val;
    this.setDisabledFields();
  }
}

private setDisabledFields() {
  this.connections.find(
    connection => connection.id == this.currentDisabledConnectionId
  ).disabled = true;
  console.log("connections: ", this.connections);
}

Notice I've changed the input to be a setter, and I saved the property as a private field.

Also note, what you posted on stackblitz doesn't remove previous disabled fields, only adds new ones (I suspect this is because you only pasted a reproduceable example).

Here is a working forked examlpe on stackBlitz