mirror of
https://github.com/Raghu-Ch/angular-challenges.git
synced 2026-02-12 13:53:03 -05:00
feat(challenge36): add solution on trackby
This commit is contained in:
58
apps/performance/ngfor-optimize/src/app/app.component.ts
Normal file
58
apps/performance/ngfor-optimize/src/app/app.component.ts
Normal file
@@ -0,0 +1,58 @@
|
||||
import { Component, OnInit, inject } from '@angular/core';
|
||||
import { FormsModule } from '@angular/forms';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatInputModule } from '@angular/material/input';
|
||||
import { PersonService } from './list.service';
|
||||
import { PersonListComponent } from './person-list.component';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
imports: [
|
||||
PersonListComponent,
|
||||
FormsModule,
|
||||
MatFormFieldModule,
|
||||
MatInputModule,
|
||||
],
|
||||
providers: [PersonService],
|
||||
selector: 'app-root',
|
||||
template: `
|
||||
<h1 class="font-semibold text-center text-3xl" title="Title">
|
||||
List of Persons
|
||||
</h1>
|
||||
|
||||
<mat-form-field class="w-3/4">
|
||||
<input
|
||||
placeholder="Add one member to the list"
|
||||
matInput
|
||||
type="text"
|
||||
[(ngModel)]="label"
|
||||
(keydown)="handleKey($event)" />
|
||||
</mat-form-field>
|
||||
|
||||
<app-person-list
|
||||
class="max-w-2xl w-3/4"
|
||||
[persons]="persons()"
|
||||
(delete)="personService.deletePerson($event)"
|
||||
(update)="personService.updatePerson($event)" />
|
||||
`,
|
||||
host: {
|
||||
class: 'flex items-center flex-col gap-5',
|
||||
},
|
||||
})
|
||||
export class AppComponent implements OnInit {
|
||||
readonly personService = inject(PersonService);
|
||||
readonly persons = this.personService.persons;
|
||||
|
||||
label = '';
|
||||
|
||||
ngOnInit(): void {
|
||||
this.personService.loadPersons();
|
||||
}
|
||||
|
||||
handleKey(event: any) {
|
||||
if (event.keyCode === 13) {
|
||||
this.personService.addPerson(this.label);
|
||||
this.label = '';
|
||||
}
|
||||
}
|
||||
}
|
||||
6
apps/performance/ngfor-optimize/src/app/app.config.ts
Normal file
6
apps/performance/ngfor-optimize/src/app/app.config.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { ApplicationConfig } from '@angular/core';
|
||||
import { provideAnimations } from '@angular/platform-browser/animations';
|
||||
|
||||
export const appConfig: ApplicationConfig = {
|
||||
providers: [provideAnimations()],
|
||||
};
|
||||
15
apps/performance/ngfor-optimize/src/app/generateList.ts
Normal file
15
apps/performance/ngfor-optimize/src/app/generateList.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
import { randEmail, randFirstName } from '@ngneat/falso';
|
||||
import { Person } from './person.model';
|
||||
|
||||
export function generateList() {
|
||||
const arr: Person[] = [];
|
||||
|
||||
for (let i = 0; i < 50; i++) {
|
||||
arr.push({
|
||||
email: randEmail(),
|
||||
name: randFirstName(),
|
||||
});
|
||||
}
|
||||
|
||||
return arr;
|
||||
}
|
||||
44
apps/performance/ngfor-optimize/src/app/list.service.ts
Normal file
44
apps/performance/ngfor-optimize/src/app/list.service.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import { Injectable, inject, signal } from '@angular/core';
|
||||
import { randEmail, randFirstName } from '@ngneat/falso';
|
||||
import { generateList } from './generateList';
|
||||
import { Person } from './person.model';
|
||||
|
||||
@Injectable()
|
||||
export class PersonService {
|
||||
private readonly fakeBackend = inject(FakeBackendService);
|
||||
readonly persons = signal<Person[]>([]);
|
||||
|
||||
loadPersons() {
|
||||
this.persons.set(generateList());
|
||||
}
|
||||
|
||||
deletePerson(email: string) {
|
||||
this.persons.set(
|
||||
this.fakeBackend
|
||||
.returnNewList(this.persons())
|
||||
.filter((p) => p.email !== email)
|
||||
);
|
||||
}
|
||||
|
||||
updatePerson(email: string) {
|
||||
this.persons.set(
|
||||
this.fakeBackend
|
||||
.returnNewList(this.persons())
|
||||
.map((p) => (p.email === email ? { email, name: randFirstName() } : p))
|
||||
);
|
||||
}
|
||||
|
||||
addPerson(name: string) {
|
||||
this.persons.set([
|
||||
{ email: randEmail(), name },
|
||||
...this.fakeBackend.returnNewList(this.persons()),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@Injectable({ providedIn: 'root' })
|
||||
export class FakeBackendService {
|
||||
returnNewList = (input: Person[]): Person[] => [
|
||||
...input.map((i) => ({ ...i })),
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import { Component, EventEmitter, Input, Output } from '@angular/core';
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Person } from './person.model';
|
||||
|
||||
@Component({
|
||||
selector: 'app-person-list',
|
||||
standalone: true,
|
||||
imports: [CommonModule],
|
||||
template: `
|
||||
<div
|
||||
*ngFor="let person of persons"
|
||||
class="flex justify-between items-center border-b">
|
||||
<h3>{{ person.name }}</h3>
|
||||
<div class="flex gap-10 py-1">
|
||||
<button
|
||||
class="border rounded-md p-2 bg-blue-500 text-white"
|
||||
(click)="update.emit(person.email)">
|
||||
UPDATE
|
||||
</button>
|
||||
<button
|
||||
class="border rounded-md p-2 bg-red-500 text-white"
|
||||
(click)="delete.emit(person.email)">
|
||||
DELETE
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
host: {
|
||||
class: 'w-full flex flex-col',
|
||||
},
|
||||
})
|
||||
export class PersonListComponent {
|
||||
@Input() persons: Person[] = [];
|
||||
@Output() delete = new EventEmitter<string>();
|
||||
@Output() update = new EventEmitter<string>();
|
||||
}
|
||||
4
apps/performance/ngfor-optimize/src/app/person.model.ts
Normal file
4
apps/performance/ngfor-optimize/src/app/person.model.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export interface Person {
|
||||
email: string;
|
||||
name: string;
|
||||
}
|
||||
Reference in New Issue
Block a user