From 43b0bde83df894e1fc0e13599e936453c2814edc Mon Sep 17 00:00:00 2001 From: "CORP\\serhii.pylypchuk" Date: Tue, 20 Jun 2023 11:58:30 +0400 Subject: [PATCH 1/3] Angular: update Angular Change Detection Specifics section --- .../85 Angular Change Detection Specifics.md | 190 +++++++++++++++--- 1 file changed, 157 insertions(+), 33 deletions(-) diff --git a/concepts/40 Angular Components/20 Component Configuration Syntax/85 Angular Change Detection Specifics.md b/concepts/40 Angular Components/20 Component Configuration Syntax/85 Angular Change Detection Specifics.md index b07462fd12..0b3706b4b0 100644 --- a/concepts/40 Angular Components/20 Component Configuration Syntax/85 Angular Change Detection Specifics.md +++ b/concepts/40 Angular Components/20 Component Configuration Syntax/85 Angular Change Detection Specifics.md @@ -2,65 +2,189 @@ Angular activates change detection on each property change. This approach backfi import { Component } from '@angular/core'; + + enum GridColumnsOption { + PersonalDetails = 0, + JobDetails = 1, + } @Component({ - selector: 'app-root', + selector: 'app-component', template: ` + [columns]="getColumns(columnsOption)"> `, - styleUrls: ['./app.component.css'] }) + export class AppComponent { - getColumns() { - return [ - { dataField: "firstName" }, - { dataField: "lastName" } - ]; + columnsOption = GridColumnsOption.PersonalDetails; + + getColumns(option: GridColumnsOption): string[] { + switch (option) { + case GridColumnsOption.PersonalDetails: + return [ + 'name', + 'address', + 'phone', + ]; + case GridColumnsOption.JobDetails: + return [ + 'name', + 'position', + 'salary', + ]; + default: + return []; + } } } In the code above, the `getColumns()` function returns an array of objects, but this array is created from scratch each time the function is called. This is what happens when you run this code: 1. The `getColumns()` function returns an array. -1. The array gets assigned to the `columns` property. This activates change detection. -1. When comparing the old and new `columns` values, the change detection mechanism calls `getColumns()` again and receives a different array. -1. The array gets assigned to the `columns` property, and the cycle repeats infinitely. +2. The array gets assigned to the `columns` property. This activates change detection. +3. When comparing the old and new `columns` values, the change detection mechanism calls `getColumns()` again and receives a different array. +4. The array gets assigned to the `columns` property, and the cycle repeats infinitely. + +To workaround this behavior, implement one of the following approaches: + +**Use a component’s class field instead of a method.** + + + import { Component } from '@angular/core'; + + enum GridColumnsOption { + PersonalDetails = 0, + JobDetails = 1, + } + + @Component({ + selector: 'app-component', + template: ` + + + `, + }) + + export class AppComponent { + columnsOption = GridColumnsOption.PersonalDetails; + + columns = { + [GridColumnsOption.PersonalDetails]: [ + 'name', + 'address', + 'phone', + ], + [GridColumnsOption.JobDetails]: [ + 'name', + 'position', + 'salary', + ], + }; + } + +**Rewrite a component’s class method to the custom [Angular pipe](https://angular.io/guide/pipes-custom-data-trans).** + + + import { + Component, + Pipe, + PipeTransform, + } from '@angular/core'; + + enum GridColumnsOption { + PersonalDetails = 0, + JobDetails = 1, + } + + @Pipe({name: 'columnsPipe'}) + + export class ExponentialStrengthPipe implements PipeTransform { + transform(columnsOption: GridColumnsOption): string[] { + switch (option) { + case GridColumnsOption.PersonalDetails: + return [ + 'name', + 'address', + 'phone', + ]; + case GridColumnsOption.JobDetails: + return [ + 'name', + 'position', + 'salary', + ]; + default: + return []; + } + } + } + + @Component({ + selector: 'app-component', + template: ` + + + `, + }) -To workaround this behavior, do one of the following: + export class AppComponent { + columnsOption = GridColumnsOption.PersonalDetails; + } -- Return an object reference, not a new object, from the function: +**Cache a returned value of the component’s method (for example, you can use universal apply pipe).** - import { Component } from '@angular/core'; + import { + Component, + Pipe, + PipeTransform, + } from '@angular/core'; + + enum GridColumnsOption { + PersonalDetails = 0, + JobDetails = 1, + } + + @Pipe({ name: 'apply' }) + + export class ApplyPipe implements PipeTransform { + transform(func: ((...args: TArgs[]) => TReturn), ...args: TArgs[]): TReturn { return func(...args); } + } @Component({ - selector: 'app-root', + selector: 'app-component', template: ` + [columns]="getColumns | apply: columnsOption"> `, - styleUrls: ['./app.component.css'] }) + export class AppComponent { - _columns: [ - { dataField: "firstName" }, - { dataField: "lastName" } - ]; - getColumns() { - return this._columns; + columnsOption = GridColumnsOption.PersonalDetails; + + getColumns = (option: GridColumnsOption): string[] => { + switch (option) { + case GridColumnsOption.PersonalDetails: + return [ + 'name', + 'address', + 'phone', + ]; + case GridColumnsOption.JobDetails: + return [ + 'firstName', + 'position', + 'salary', + ]; + default: + return []; + } } } -- Switch change detection to the `OnPush` mode: - - - import { Component, ChangeDetectionStrategy } from '@angular/core'; - - @Component({ - // ... - changeDetection: ChangeDetectionStrategy.OnPush - }) - // ... +[note]We recommend you to use an arrow function with this approach. From e6d0b8b6ebeac2a51b9cd5f0106bbd2db15a7eb0 Mon Sep 17 00:00:00 2001 From: Serge Pilipchuk <112853396+sergepilipchuk@users.noreply.github.com> Date: Wed, 21 Jun 2023 10:20:04 +0400 Subject: [PATCH 2/3] Apply suggestions from code review Co-authored-by: Ilya Vinogradov <48182348+williamvinogradov@users.noreply.github.com> --- .../85 Angular Change Detection Specifics.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/concepts/40 Angular Components/20 Component Configuration Syntax/85 Angular Change Detection Specifics.md b/concepts/40 Angular Components/20 Component Configuration Syntax/85 Angular Change Detection Specifics.md index 0b3706b4b0..e67a5a83a7 100644 --- a/concepts/40 Angular Components/20 Component Configuration Syntax/85 Angular Change Detection Specifics.md +++ b/concepts/40 Angular Components/20 Component Configuration Syntax/85 Angular Change Detection Specifics.md @@ -100,7 +100,6 @@ To workaround this behavior, implement one of the following approaches: } @Pipe({name: 'columnsPipe'}) - export class ExponentialStrengthPipe implements PipeTransform { transform(columnsOption: GridColumnsOption): string[] { switch (option) { @@ -130,7 +129,6 @@ To workaround this behavior, implement one of the following approaches: `, }) - export class AppComponent { columnsOption = GridColumnsOption.PersonalDetails; } @@ -150,7 +148,6 @@ To workaround this behavior, implement one of the following approaches: } @Pipe({ name: 'apply' }) - export class ApplyPipe implements PipeTransform { transform(func: ((...args: TArgs[]) => TReturn), ...args: TArgs[]): TReturn { return func(...args); } } @@ -163,7 +160,6 @@ To workaround this behavior, implement one of the following approaches: `, }) - export class AppComponent { columnsOption = GridColumnsOption.PersonalDetails; From 76cedfade744dc1925306b5118d787f1b67363c4 Mon Sep 17 00:00:00 2001 From: Serge Pilipchuk <112853396+sergepilipchuk@users.noreply.github.com> Date: Wed, 21 Jun 2023 18:49:51 +0400 Subject: [PATCH 3/3] Apply suggestions from code review Co-authored-by: Albert Totten <49917542+albertov05@users.noreply.github.com> --- .../85 Angular Change Detection Specifics.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/concepts/40 Angular Components/20 Component Configuration Syntax/85 Angular Change Detection Specifics.md b/concepts/40 Angular Components/20 Component Configuration Syntax/85 Angular Change Detection Specifics.md index e67a5a83a7..89690b647b 100644 --- a/concepts/40 Angular Components/20 Component Configuration Syntax/85 Angular Change Detection Specifics.md +++ b/concepts/40 Angular Components/20 Component Configuration Syntax/85 Angular Change Detection Specifics.md @@ -47,7 +47,7 @@ In the code above, the `getColumns()` function returns an array of objects, but 3. When comparing the old and new `columns` values, the change detection mechanism calls `getColumns()` again and receives a different array. 4. The array gets assigned to the `columns` property, and the cycle repeats infinitely. -To workaround this behavior, implement one of the following approaches: +To work around this behavior, implement one of the following techniques: **Use a component’s class field instead of a method.** @@ -85,7 +85,7 @@ To workaround this behavior, implement one of the following approaches: }; } -**Rewrite a component’s class method to the custom [Angular pipe](https://angular.io/guide/pipes-custom-data-trans).** +**Rewrite a component’s class method to a custom [Angular pipe](https://angular.io/guide/pipes-custom-data-trans).** import { @@ -133,7 +133,7 @@ To workaround this behavior, implement one of the following approaches: columnsOption = GridColumnsOption.PersonalDetails; } -**Cache a returned value of the component’s method (for example, you can use universal apply pipe).** +**Cache the return value of the component’s method (for example, you can use a universal apply pipe).** import { @@ -183,4 +183,4 @@ To workaround this behavior, implement one of the following approaches: } } -[note]We recommend you to use an arrow function with this approach. +[note]We recommend that you use an arrow function with this technique.