From 1a2a32e312fc1b1633089e9ca8cca0601d8f5f0f Mon Sep 17 00:00:00 2001 From: lukasss88 Date: Sun, 30 Nov 2025 13:12:12 +0100 Subject: [PATCH] feat: solution --- .../src/app/app.component.ts | 14 +++---- .../src/app/person-list.component.ts | 32 ++------------- .../src/app/person.component.ts | 36 +++++++++++++++++ .../src/app/person.form.component.ts | 40 +++++++++++++++++++ .../src/app/person.service.ts | 20 ++++++++++ .../src/app/random.component.ts | 3 +- 6 files changed, 107 insertions(+), 38 deletions(-) create mode 100644 apps/performance/34-default-vs-onpush/src/app/person.component.ts create mode 100644 apps/performance/34-default-vs-onpush/src/app/person.form.component.ts create mode 100644 apps/performance/34-default-vs-onpush/src/app/person.service.ts diff --git a/apps/performance/34-default-vs-onpush/src/app/app.component.ts b/apps/performance/34-default-vs-onpush/src/app/app.component.ts index 88b0a6571..2e9ac1669 100644 --- a/apps/performance/34-default-vs-onpush/src/app/app.component.ts +++ b/apps/performance/34-default-vs-onpush/src/app/app.component.ts @@ -1,21 +1,17 @@ import { Component } from '@angular/core'; -import { randFirstName } from '@ngneat/falso'; -import { PersonListComponent } from './person-list.component'; +import { PersonComponent } from './person.component'; import { RandomComponent } from './random.component'; @Component({ - imports: [PersonListComponent, RandomComponent], + imports: [RandomComponent, PersonComponent], selector: 'app-root', template: `
- - + +
`, }) -export class AppComponent { - girlList = randFirstName({ gender: 'female', length: 10 }); - boyList = randFirstName({ gender: 'male', length: 10 }); -} +export class AppComponent {} diff --git a/apps/performance/34-default-vs-onpush/src/app/person-list.component.ts b/apps/performance/34-default-vs-onpush/src/app/person-list.component.ts index e34a39e87..770b1e13f 100644 --- a/apps/performance/34-default-vs-onpush/src/app/person-list.component.ts +++ b/apps/performance/34-default-vs-onpush/src/app/person-list.component.ts @@ -1,7 +1,6 @@ -import { Component, input } from '@angular/core'; +import { ChangeDetectionStrategy, Component, input } from '@angular/core'; import { CDFlashingDirective } from '@angular-challenges/shared/directives'; -import { TitleCasePipe } from '@angular/common'; import { FormsModule } from '@angular/forms'; import { MatChipsModule } from '@angular/material/chips'; import { MatFormFieldModule } from '@angular/material/form-field'; @@ -17,24 +16,10 @@ import { MatListModule } from '@angular/material/list'; MatInputModule, MatChipsModule, CDFlashingDirective, - TitleCasePipe, ], template: ` -

- {{ title() | titlecase }} -

- - - - - - @if (names()?.length === 0) { + @if (names().length === 0) {
Empty list
} @for (name of names(); track name) { @@ -46,7 +31,7 @@ import { MatListModule } from '@angular/material/list'; } - @if (names()?.length !== 0) { + @if (names().length !== 0) { }
@@ -54,17 +39,8 @@ import { MatListModule } from '@angular/material/list'; host: { class: 'w-full flex flex-col items-center', }, + changeDetection: ChangeDetectionStrategy.OnPush, }) export class PersonListComponent { names = input([]); - title = input(''); - - label = ''; - - handleKey(event: KeyboardEvent) { - if (event.key === 'Enter') { - this.names()?.unshift(this.label); - this.label = ''; - } - } } diff --git a/apps/performance/34-default-vs-onpush/src/app/person.component.ts b/apps/performance/34-default-vs-onpush/src/app/person.component.ts new file mode 100644 index 000000000..31736ebf1 --- /dev/null +++ b/apps/performance/34-default-vs-onpush/src/app/person.component.ts @@ -0,0 +1,36 @@ +import { TitleCasePipe } from '@angular/common'; +import { Component, inject, input, OnInit } from '@angular/core'; +import { PersonListComponent } from './person-list.component'; +import { PersonFormComponent } from './person.form.component'; +import { PersonService } from './person.service'; + +@Component({ + selector: 'app-person', + imports: [TitleCasePipe, PersonListComponent, PersonFormComponent], + template: ` +

+ {{ title() | titlecase }} +

+ + + + `, + host: { + class: 'w-full flex flex-col items-center', + }, + providers: [PersonService], +}) +export class PersonComponent implements OnInit { + service = inject(PersonService); + title = input(''); + gender = input<'male' | 'female'>('male'); + names = this.service.list; + + ngOnInit(): void { + this.service.initList(this.gender()); + } + + onAddLabel(label: string) { + this.service.add(label); + } +} diff --git a/apps/performance/34-default-vs-onpush/src/app/person.form.component.ts b/apps/performance/34-default-vs-onpush/src/app/person.form.component.ts new file mode 100644 index 000000000..421dcb4b9 --- /dev/null +++ b/apps/performance/34-default-vs-onpush/src/app/person.form.component.ts @@ -0,0 +1,40 @@ +import { CDFlashingDirective } from '@angular-challenges/shared/directives'; +import { ChangeDetectionStrategy, Component, output } from '@angular/core'; +import { FormsModule } from '@angular/forms'; +import { MatFormFieldModule } from '@angular/material/form-field'; +import { MatInputModule } from '@angular/material/input'; + +@Component({ + selector: 'person-form', + imports: [ + FormsModule, + MatFormFieldModule, + MatInputModule, + CDFlashingDirective, + ], + template: ` + + + + `, + host: { + class: 'w-full flex flex-col items-center', + }, + changeDetection: ChangeDetectionStrategy.OnPush, +}) +export class PersonFormComponent { + label = ''; + addLabel = output(); + + handleKey(event: KeyboardEvent) { + if (event.key === 'Enter') { + this.addLabel.emit(this.label); + this.label = ''; + } + } +} diff --git a/apps/performance/34-default-vs-onpush/src/app/person.service.ts b/apps/performance/34-default-vs-onpush/src/app/person.service.ts new file mode 100644 index 000000000..31e5a13c4 --- /dev/null +++ b/apps/performance/34-default-vs-onpush/src/app/person.service.ts @@ -0,0 +1,20 @@ +import { Injectable, signal } from '@angular/core'; +import { randFirstName } from '@ngneat/falso'; + +@Injectable() +export class PersonService { + private _list = signal([]); + list = this._list.asReadonly(); + + initList(gender: 'male' | 'female') { + if (gender === 'male') { + this._list.set(randFirstName({ gender: 'male', length: 10 })); + } else { + this._list.set(randFirstName({ gender: 'female', length: 10 })); + } + } + + add(name: string) { + this._list.update((names) => [...names, name]); + } +} diff --git a/apps/performance/34-default-vs-onpush/src/app/random.component.ts b/apps/performance/34-default-vs-onpush/src/app/random.component.ts index 71479e28d..1e36352ac 100644 --- a/apps/performance/34-default-vs-onpush/src/app/random.component.ts +++ b/apps/performance/34-default-vs-onpush/src/app/random.component.ts @@ -1,5 +1,5 @@ import { CDFlashingDirective } from '@angular-challenges/shared/directives'; -import { Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component } from '@angular/core'; @Component({ selector: 'app-random', @@ -7,5 +7,6 @@ import { Component } from '@angular/core';
I do nothing but I'm here
`, imports: [CDFlashingDirective], + changeDetection: ChangeDetectionStrategy.OnPush, }) export class RandomComponent {}