Triet Nguyen
Triet Nguyen

Reputation: 821

Angular4 ChangeDetection for Input object which is an item of array

I know that Angular 2+ will trigger change detection when you change reference of an object/array. I did change referenece its but it seems to nothing happens in my case.

Parent Component

@Component({
   selector: 'parent-component',
   templateUrl: `
      <ul>
        <ng-template ngFor let-tabHeader[ngForOf]="tabHeaders" let-i="index">
            <li *ngIf="tabHeader.visible"
                id="{{tabHeader.tabID}}"
                [ngClass]="{'active': tabHeader.active, 'disabled': tabHeader.disabled}"
                (click)="clickOtherTabsHeader(otherTabHeader, $event)">
                <child-component [data]="tabHeader" [active]="tabHeader.active"></child-component>
            </li>
        </ng-template>
      </ul>
   `,
})
export class ParentComponent {
     private _selectors: AppSelectors;
     public tabHeaders: any[];

     ngOnInit() {
        this.tabHeaders = [{}, {}, {}]; // loaded data
     }

     // listen an stream from state
     this._selectors.stateData$
         .filter(stateData=> !!stateData)
         .subscribe(stateData => {
            // DO BUSINESS
            // update an tab on processing, for example first tab. But it don't trigger change detection for child component
            this.tabHeaders[0] = {...tabHeaders[0] };
         };
}

Child Component

@Component({
   selector: 'child-component',
   templateUrl: `
     <div>{{data.tabName}}</div>
     <div>{{data.value}}</div>
   `,
})
export class ChildComponent implements OnChanges {
    private _data: any;        

    @Input('data') set data(tabHeader: any) {
        // set data business
        this._data = tabHeader;
    }

    get data(): any {
        return this._data;
    }

    ngOnChanges(changes: SimpleChanges): void {
        console.log(`${this._data.tabName} OnChanges`, changes);

        if (!changes.data.previousValue) return;

        // this line has never reached
        console.log(`${this._data.tabName} OnUpdated`, changes);
    }
}

Please review the code that I was mistaked to run change detection. Thanks in advance.

Upvotes: 0

Views: 194

Answers (1)

user3740359
user3740359

Reputation: 405

you are only updating one item inside the array via this.tabHeaders[0] = {...tabHeaders[0] };

that does not trigger change detection because the entire array reference stays the same. you basically need to clone the array to a new reference, e.g. try to add this.tabHeader = [...this.tabHeaders];

Upvotes: 1

Related Questions