Skip to content

Commit 2d39a40

Browse files
Chore/factor out list component (#19)
* wip * [#16] Factor list component out Elephants-list and Lions-list were duplicate code. Factored them out into an animals-lsit component in Core.
1 parent 0a9b540 commit 2d39a40

14 files changed

+109
-86
lines changed

src/app/app.routes.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
import { ElephantListComponent } from './elephants/elephant-list/elephant-list.component';
2-
import { LionListComponent } from './lions/lion-list/lion-list.component';
1+
import { ElephantsPageComponent } from './elephants/elephants-page.container';
2+
import { LionsPageComponent } from './lions/lions-page.container';
33
import { FeedbackFormComponent } from './feedback/feedback-form/feedback-form.component';
44

55
export const appRoutes = [
66
{ path: '', redirectTo: '/elephants', pathMatch: 'full' },
7-
{ path: 'elephants', component: ElephantListComponent },
8-
{ path: 'lions', component: LionListComponent },
7+
{ path: 'elephants', component: ElephantsPageComponent },
8+
{ path: 'lions', component: LionsPageComponent },
99
{ path: 'feedback', component: FeedbackFormComponent },
1010
];
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<h2>We have {{ animalsName }}!</h2>
2+
3+
<zoo-spinner *ngIf="loading | async">
4+
</zoo-spinner>
5+
6+
<ul>
7+
<li *ngFor="let animal of animals | async; trackBy:getAnimalName">
8+
{{ animal.name }}
9+
</li>
10+
</ul>
11+
12+
<zoo-error-well *ngIf="error | async">
13+
</zoo-error-well>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { Component, Input } from '@angular/core';
2+
import { Observable } from 'rxjs/Observable';
3+
4+
@Component({
5+
selector: 'zoo-animal-list',
6+
templateUrl: './animal-list.component.html',
7+
styleUrls: ['./animal-list.component.css']
8+
})
9+
export class AnimalListComponent {
10+
@Input() animalsName: string;
11+
@Input() animals: Observable<any[]>;
12+
@Input() loading: Observable<boolean>;
13+
@Input() error: Observable<any>;
14+
15+
// Since we're observing an array of items, we need to set up a 'trackBy'
16+
// parameter so Angular doesn't tear down and rebuild the list's DOM every
17+
// time there's an update.
18+
getAnimalName(_, animal) {
19+
return animal.name;
20+
}
21+
}

src/app/core/core.module.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,20 @@ import { CommonModule } from '@angular/common';
33

44
import { SpinnerComponent } from './spinner/spinner.component';
55
import { ErrorWellComponent } from './error-well/error-well.component';
6+
import { AnimalListComponent } from './animal-list/animal-list.component';
67

78
@NgModule({
89
declarations: [
910
SpinnerComponent,
1011
ErrorWellComponent,
12+
AnimalListComponent,
1113
],
1214
providers: [],
1315
imports: [ CommonModule ],
1416
exports: [
1517
SpinnerComponent,
1618
ErrorWellComponent,
19+
AnimalListComponent,
1720
],
1821
})
1922
export class CoreModule {}

src/app/elephants/elephant-list/elephant-list.component.html

Lines changed: 0 additions & 13 deletions
This file was deleted.

src/app/elephants/elephant-list/elephant-list.component.ts

Lines changed: 0 additions & 25 deletions
This file was deleted.
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Component } from '@angular/core';
2+
import { select } from '@angular-redux/store';
3+
import { Observable } from 'rxjs/Observable';
4+
5+
/**
6+
* In Redux terminology, a 'container' is a component that knows about the store.
7+
* It selects data, and marshals it into a set of 'presentational' (or non-redux-connected)
8+
* components for display.
9+
*
10+
* The 'page-level' components that get attached to the router are usually containers;
11+
* but not all containers need to be page-level components.
12+
*/
13+
@Component({
14+
template: `
15+
<zoo-animal-list
16+
animalsName="Elephants"
17+
[animals]="animals$"
18+
[loading]="loading$"
19+
[error]="error$">
20+
</zoo-animal-list>
21+
`
22+
})
23+
export class ElephantsPageComponent {
24+
// Shorthand for
25+
// constructor(ngRedux: NgRedux {
26+
// this.animals$ = ngRedux.select(['elephants', 'items']);
27+
// })
28+
@select(['elephants', 'items']) readonly animals$: Observable<any[]>;
29+
@select(['elephants', 'loading']) readonly loading$: Observable<boolean>;
30+
@select(['elephants', 'error']) readonly error$: Observable<any>;
31+
}

src/app/elephants/elephants.module.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { NgModule } from '@angular/core';
22
import { CommonModule } from '@angular/common';
33

4-
import { ElephantListComponent } from './elephant-list/elephant-list.component';
4+
import { ElephantsPageComponent } from './elephants-page.container';
55
import { ElephantsEpics } from './elephants.epics';
66
import { ElephantsService } from './elephants.service';
77
import { ElephantsActions } from './elephants.actions';
88
import { CoreModule } from '../core/core.module';
99

1010
@NgModule({
11-
declarations: [ ElephantListComponent ],
11+
declarations: [ElephantsPageComponent],
12+
exports: [ElephantsPageComponent],
1213
providers: [
1314
ElephantsEpics,
1415
ElephantsService,
@@ -18,6 +19,5 @@ import { CoreModule } from '../core/core.module';
1819
CommonModule,
1920
CoreModule,
2021
],
21-
exports: [ ElephantListComponent ],
2222
})
2323
export class ElephantsModule {}

src/app/lions/lion-list/lion-list.component.css

Whitespace-only changes.

0 commit comments

Comments
 (0)