0

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.

2
  • hi you need to read this article : alligator.io/angular/change-detection-strategy you can call cdref.detectchanges() after this.tabHeaders[0] = {...this.tabHeaders[0] }; to force angular to detect changes Commented Dec 20, 2019 at 7:44
  • hi, my component do not use ChangeStrategy, so I think change detection work as normal when you update reference of @Input directive. That will trigger change detection, right? Commented Dec 23, 2019 at 4:58

1 Answer 1

1

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];

Sign up to request clarification or add additional context in comments.

1 Comment

hi, thank you, but my @Input is an item of the array, that will point to reference of that item. I don't know which is exact mechanism of Angular change detection. If I pass array tabHeaders into child-component, then I will update array tabHeaders to new reference, but this case is opposite of it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.