Skip to content

Commit 459e831

Browse files
committed
feat(Answer:1): projection
1 parent f3be3ee commit 459e831

File tree

5 files changed

+119
-78
lines changed

5 files changed

+119
-78
lines changed
Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,54 @@
11
import { Component, OnInit } from '@angular/core';
2+
import { CityStore } from '../../data-access/city.store';
3+
import {
4+
FakeHttpService,
5+
randomCity,
6+
} from '../../data-access/fake-http.service';
7+
import { City } from '../../model/city.model';
8+
import { CardComponent } from '../../ui/card/card.component';
29

310
@Component({
411
selector: 'app-city-card',
5-
template: 'TODO City',
6-
imports: [],
12+
template: `
13+
<app-card
14+
[list]="cities"
15+
[getListItemName]="getListItemName"
16+
class="bg-light-green"
17+
(addNewItemEvent)="handleAddNewItemEvent()"
18+
(deleteItemEvent)="handleDeleteItemEvent($event)">
19+
<div card-img>
20+
<img src="assets/img/city.png" width="200px" />
21+
</div>
22+
</app-card>
23+
`,
24+
styles: [
25+
`
26+
.bg-light-green {
27+
background-color: rgba(0, 250, 0, 0.1);
28+
}
29+
`,
30+
],
31+
imports: [CardComponent],
732
})
833
export class CityCardComponent implements OnInit {
9-
constructor() {}
34+
cities: City[] = [];
35+
getListItemName = (city: City) => city.name;
1036

11-
ngOnInit(): void {}
37+
constructor(
38+
private http: FakeHttpService,
39+
private store: CityStore,
40+
) {}
41+
42+
ngOnInit(): void {
43+
this.http.fetchCities$.subscribe((e) => this.store.addAll(e));
44+
this.store.cities$.subscribe((e) => (this.cities = e));
45+
}
46+
47+
handleAddNewItemEvent() {
48+
this.store.addOne(randomCity());
49+
}
50+
51+
handleDeleteItemEvent(id: number) {
52+
this.store.deleteOne(id);
53+
}
1254
}
Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { Component, OnInit } from '@angular/core';
2-
import { FakeHttpService } from '../../data-access/fake-http.service';
2+
import {
3+
FakeHttpService,
4+
randStudent,
5+
} from '../../data-access/fake-http.service';
36
import { StudentStore } from '../../data-access/student.store';
4-
import { CardType } from '../../model/card.model';
57
import { Student } from '../../model/student.model';
68
import { CardComponent } from '../../ui/card/card.component';
79

@@ -10,12 +12,18 @@ import { CardComponent } from '../../ui/card/card.component';
1012
template: `
1113
<app-card
1214
[list]="students"
13-
[type]="cardType"
14-
customClass="bg-light-green"></app-card>
15+
[getListItemName]="getListItemName"
16+
class="bg-light-green"
17+
(addNewItemEvent)="handleAddNewItemEvent()"
18+
(deleteItemEvent)="handleDeleteItemEvent($event)">
19+
<div card-img>
20+
<img src="assets/img/student.webp" width="200px" />
21+
</div>
22+
</app-card>
1523
`,
1624
styles: [
1725
`
18-
::ng-deep .bg-light-green {
26+
.bg-light-green {
1927
background-color: rgba(0, 250, 0, 0.1);
2028
}
2129
`,
@@ -24,7 +32,7 @@ import { CardComponent } from '../../ui/card/card.component';
2432
})
2533
export class StudentCardComponent implements OnInit {
2634
students: Student[] = [];
27-
cardType = CardType.STUDENT;
35+
getListItemName = (student: Student) => student.firstName;
2836

2937
constructor(
3038
private http: FakeHttpService,
@@ -36,4 +44,12 @@ export class StudentCardComponent implements OnInit {
3644

3745
this.store.students$.subscribe((s) => (this.students = s));
3846
}
47+
48+
handleAddNewItemEvent() {
49+
this.store.addOne(randStudent());
50+
}
51+
52+
handleDeleteItemEvent(id: number) {
53+
this.store.deleteOne(id);
54+
}
3955
}
Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import { Component, OnInit } from '@angular/core';
2-
import { FakeHttpService } from '../../data-access/fake-http.service';
2+
import {
3+
FakeHttpService,
4+
randTeacher,
5+
} from '../../data-access/fake-http.service';
36
import { TeacherStore } from '../../data-access/teacher.store';
4-
import { CardType } from '../../model/card.model';
57
import { Teacher } from '../../model/teacher.model';
68
import { CardComponent } from '../../ui/card/card.component';
79

@@ -10,12 +12,18 @@ import { CardComponent } from '../../ui/card/card.component';
1012
template: `
1113
<app-card
1214
[list]="teachers"
13-
[type]="cardType"
14-
customClass="bg-light-red"></app-card>
15+
[getListItemName]="getListItemName"
16+
class="bg-light-red"
17+
(addNewItemEvent)="handleAddNewItemEvent()"
18+
(deleteItemEvent)="handleDeleteItemEvent($event)">
19+
<div card-img>
20+
<img src="assets/img/teacher.png" width="200px" />
21+
</div>
22+
</app-card>
1523
`,
1624
styles: [
1725
`
18-
::ng-deep .bg-light-red {
26+
.bg-light-red {
1927
background-color: rgba(250, 0, 0, 0.1);
2028
}
2129
`,
@@ -24,7 +32,7 @@ import { CardComponent } from '../../ui/card/card.component';
2432
})
2533
export class TeacherCardComponent implements OnInit {
2634
teachers: Teacher[] = [];
27-
cardType = CardType.TEACHER;
35+
getListItemName = (teacher: Teacher) => teacher.firstName;
2836

2937
constructor(
3038
private http: FakeHttpService,
@@ -36,4 +44,12 @@ export class TeacherCardComponent implements OnInit {
3644

3745
this.store.teachers$.subscribe((t) => (this.teachers = t));
3846
}
47+
48+
handleAddNewItemEvent() {
49+
this.store.addOne(randTeacher());
50+
}
51+
52+
handleDeleteItemEvent(id: number) {
53+
this.store.deleteOne(id);
54+
}
3955
}
Lines changed: 26 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,39 @@
1-
import { NgFor, NgIf } from '@angular/common';
2-
import { Component, Input } from '@angular/core';
3-
import { randStudent, randTeacher } from '../../data-access/fake-http.service';
4-
import { StudentStore } from '../../data-access/student.store';
5-
import { TeacherStore } from '../../data-access/teacher.store';
6-
import { CardType } from '../../model/card.model';
1+
import { NgFor } from '@angular/common';
2+
import { Component, EventEmitter, Input, Output } from '@angular/core';
73
import { ListItemComponent } from '../list-item/list-item.component';
84

95
@Component({
106
selector: 'app-card',
117
template: `
12-
<div
13-
class="flex w-fit flex-col gap-3 rounded-md border-2 border-black p-4"
14-
[class]="customClass">
15-
<img
16-
*ngIf="type === CardType.TEACHER"
17-
src="assets/img/teacher.png"
18-
width="200px" />
19-
<img
20-
*ngIf="type === CardType.STUDENT"
21-
src="assets/img/student.webp"
22-
width="200px" />
23-
24-
<section>
25-
<app-list-item
26-
*ngFor="let item of list"
27-
[name]="item.firstName"
28-
[id]="item.id"
29-
[type]="type"></app-list-item>
30-
</section>
31-
32-
<button
33-
class="rounded-sm border border-blue-500 bg-blue-300 p-2"
34-
(click)="addNewItem()">
35-
Add
36-
</button>
37-
</div>
8+
<ng-content select="[card-img]"></ng-content>
9+
<section>
10+
<app-list-item
11+
*ngFor="let item of list"
12+
[name]="getListItemName(item)"
13+
[id]="item.id"
14+
(deleteItemEvent)="handleDeleteItemEvent($event)"></app-list-item>
15+
</section>
16+
<button
17+
class="rounded-sm border border-blue-500 bg-blue-300 p-2"
18+
(click)="addNewItem()">
19+
Add
20+
</button>
3821
`,
39-
imports: [NgIf, NgFor, ListItemComponent],
22+
imports: [NgFor, ListItemComponent],
23+
host: {
24+
class: 'border-2 border-black rounded-md p-4 w-fit flex flex-col gap-3',
25+
},
4026
})
4127
export class CardComponent {
4228
@Input() list: any[] | null = null;
43-
@Input() type!: CardType;
44-
@Input() customClass = '';
45-
46-
CardType = CardType;
47-
48-
constructor(
49-
private teacherStore: TeacherStore,
50-
private studentStore: StudentStore,
51-
) {}
29+
@Input({ required: true }) getListItemName!: (listItem: any) => string;
30+
@Output() deleteItemEvent = new EventEmitter<number>();
31+
@Output() addNewItemEvent = new EventEmitter<void>();
5232

5333
addNewItem() {
54-
if (this.type === CardType.TEACHER) {
55-
this.teacherStore.addOne(randTeacher());
56-
} else if (this.type === CardType.STUDENT) {
57-
this.studentStore.addOne(randStudent());
58-
}
34+
this.addNewItemEvent.emit();
35+
}
36+
handleDeleteItemEvent(id: number) {
37+
this.deleteItemEvent.emit(id);
5938
}
6039
}
Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
import { Component, Input } from '@angular/core';
2-
import { StudentStore } from '../../data-access/student.store';
3-
import { TeacherStore } from '../../data-access/teacher.store';
4-
import { CardType } from '../../model/card.model';
1+
import { Component, EventEmitter, Input, Output } from '@angular/core';
52

63
@Component({
74
selector: 'app-list-item',
@@ -18,18 +15,9 @@ import { CardType } from '../../model/card.model';
1815
export class ListItemComponent {
1916
@Input() id!: number;
2017
@Input() name!: string;
21-
@Input() type!: CardType;
22-
23-
constructor(
24-
private teacherStore: TeacherStore,
25-
private studentStore: StudentStore,
26-
) {}
18+
@Output() deleteItemEvent = new EventEmitter<number>();
2719

2820
delete(id: number) {
29-
if (this.type === CardType.TEACHER) {
30-
this.teacherStore.deleteOne(id);
31-
} else if (this.type === CardType.STUDENT) {
32-
this.studentStore.deleteOne(id);
33-
}
21+
this.deleteItemEvent.emit(id);
3422
}
3523
}

0 commit comments

Comments
 (0)