|
1 | | -import { Component, Input, ChangeDetectionStrategy, OnInit } from '@angular/core'; |
2 | | -import { NgRedux, dispatch, select, ObservableStore } from '@angular-redux/store'; |
| 1 | +import { Component, Input, ChangeDetectionStrategy } from '@angular/core'; |
| 2 | +import { NgRedux, dispatch, select, select$, WithSubStore } from '@angular-redux/store'; |
3 | 3 | import { Observable } from 'rxjs/Observable'; |
4 | | -import 'rxjs/add/observable/combineLatest'; |
5 | 4 |
|
6 | 5 | import { IAppState } from '../../store/model'; |
7 | 6 | import { animalComponentReducer } from './reducers'; |
| 7 | +import { IAnimal } from '../model'; |
| 8 | + |
| 9 | +export const toSubTotal = (obs$: Observable<IAnimal>): Observable<number> => |
| 10 | + obs$.map(s => s.ticketPrice * s.tickets); |
8 | 11 |
|
9 | 12 | /** |
10 | 13 | * Fractal component example. |
11 | 14 | */ |
| 15 | +@WithSubStore({ |
| 16 | + basePathMethodName: 'getBasePath', |
| 17 | + localReducer: animalComponentReducer, |
| 18 | +}) |
12 | 19 | @Component({ |
13 | 20 | selector: 'zoo-animal', |
14 | 21 | templateUrl: './component.html', |
15 | 22 | styleUrls: ['./component.css'], |
16 | 23 | changeDetection: ChangeDetectionStrategy.OnPush, |
17 | 24 | }) |
18 | | -export class AnimalComponent implements OnInit { |
| 25 | +export class AnimalComponent { |
19 | 26 | static readonly ADD_TICKET = 'ADD_TICKET'; |
20 | 27 | static readonly REMOVE_TICKET = 'REMOVE_TICKET'; |
21 | 28 |
|
22 | 29 | @Input() key: string; |
23 | 30 | @Input() animalType: string; |
24 | 31 |
|
25 | | - private subStore: ObservableStore<any>; |
26 | | - |
27 | | - name$: Observable<string>; |
28 | | - numTickets$: Observable<number>; |
29 | | - ticketPrice$: Observable<number>; |
30 | | - subTotal$: Observable<number>; |
31 | | - |
32 | | - constructor(private ngRedux: NgRedux<IAppState>) {} |
33 | | - |
34 | | - addTicket = () => this.subStore.dispatch({ type: 'ADD_TICKET' }); |
35 | | - removeTicket = () => this.subStore.dispatch({ type: 'REMOVE_TICKET' }); |
| 32 | + @select() readonly name$: Observable<string>; |
| 33 | + @select('tickets') readonly numTickets$: Observable<number>; |
| 34 | + @select('ticketPrice') readonly ticketPrice$: Observable<number>; |
| 35 | + @select$(null, toSubTotal) readonly subTotal$: Observable<number>; |
36 | 36 |
|
37 | | - // Can't be done in the constructor because it relies on data from the |
38 | | - // inputs. |
39 | | - ngOnInit() { |
40 | | - this.subStore = this.ngRedux.configureSubStore<any>( |
41 | | - [this.animalType, 'items', this.key], |
42 | | - animalComponentReducer); |
43 | | - this.name$ = this.subStore.select('name'); |
44 | | - this.numTickets$ = this.subStore.select(['tickets']) |
45 | | - .map(n => n || 0); |
46 | | - this.ticketPrice$ = this.subStore.select('ticketPrice') |
47 | | - .map(n => n || 1); |
| 37 | + getBasePath = () => this.key ? |
| 38 | + [ this.animalType, 'items', this.key ] : |
| 39 | + null; |
48 | 40 |
|
49 | | - this.subTotal$ = Observable.combineLatest( |
50 | | - this.numTickets$, |
51 | | - this.ticketPrice$, |
52 | | - (num, price) => num * price); |
53 | | - } |
| 41 | + @dispatch() addTicket = () => ({ type: 'ADD_TICKET' }); |
| 42 | + @dispatch() removeTicket = () => ({ type: 'REMOVE_TICKET' }); |
54 | 43 | } |
0 commit comments