| @@ -336,6 +336,11 @@ | |||||
| "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.2.4.tgz", | "resolved": "https://registry.npmjs.org/@firebase/webchannel-wrapper/-/webchannel-wrapper-0.2.4.tgz", | ||||
| "integrity": "sha512-jEpglcwMlwdXc/JgvJaJtCSkPMktnFeI0gAZxPrmbJxKVzMZJ2zM582NbW/r6M22pSdNWjcWeg1I2LRg3jQGQA==" | "integrity": "sha512-jEpglcwMlwdXc/JgvJaJtCSkPMktnFeI0gAZxPrmbJxKVzMZJ2zM582NbW/r6M22pSdNWjcWeg1I2LRg3jQGQA==" | ||||
| }, | }, | ||||
| "@ngrx/store": { | |||||
| "version": "4.1.1", | |||||
| "resolved": "https://registry.npmjs.org/@ngrx/store/-/store-4.1.1.tgz", | |||||
| "integrity": "sha1-aA403yd16IUnVO13f/rJW9gbfeA=" | |||||
| }, | |||||
| "@ngtools/json-schema": { | "@ngtools/json-schema": { | ||||
| "version": "1.1.0", | "version": "1.1.0", | ||||
| "resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.1.0.tgz", | "resolved": "https://registry.npmjs.org/@ngtools/json-schema/-/json-schema-1.1.0.tgz", | ||||
| @@ -21,6 +21,7 @@ | |||||
| "@angular/platform-browser": "^5.0.0", | "@angular/platform-browser": "^5.0.0", | ||||
| "@angular/platform-browser-dynamic": "^5.0.0", | "@angular/platform-browser-dynamic": "^5.0.0", | ||||
| "@angular/router": "^5.0.0", | "@angular/router": "^5.0.0", | ||||
| "@ngrx/store": "^4.1.1", | |||||
| "bootstrap": "^3.3.7", | "bootstrap": "^3.3.7", | ||||
| "core-js": "^2.4.1", | "core-js": "^2.4.1", | ||||
| "firebase": "^4.6.2", | "firebase": "^4.6.2", | ||||
| @@ -1,6 +1,7 @@ | |||||
| import { BrowserModule } from '@angular/platform-browser'; | import { BrowserModule } from '@angular/platform-browser'; | ||||
| import { NgModule } from '@angular/core'; | import { NgModule } from '@angular/core'; | ||||
| import { HttpClientModule } from '@angular/common/http'; | import { HttpClientModule } from '@angular/common/http'; | ||||
| import { StoreModule } from '@ngrx/store'; | |||||
| import { AppComponent } from './app.component'; | import { AppComponent } from './app.component'; | ||||
| import { AppRoutingModule } from './app-routing.module'; | import { AppRoutingModule } from './app-routing.module'; | ||||
| @@ -8,6 +9,7 @@ import { SharedModule } from './shared/shared.module'; | |||||
| import { ShoppingListModule } from './shopping-list/shopping-list.module'; | import { ShoppingListModule } from './shopping-list/shopping-list.module'; | ||||
| import { AuthModule } from './auth/auth.module'; | import { AuthModule } from './auth/auth.module'; | ||||
| import { CoreModule } from './core/core.module'; | import { CoreModule } from './core/core.module'; | ||||
| import { shoppingListReducer } from './shopping-list/ngrx/shopping-list.reducers'; | |||||
| @NgModule({ | @NgModule({ | ||||
| declarations: [ | declarations: [ | ||||
| @@ -20,7 +22,8 @@ import { CoreModule } from './core/core.module'; | |||||
| SharedModule, | SharedModule, | ||||
| ShoppingListModule, | ShoppingListModule, | ||||
| AuthModule, | AuthModule, | ||||
| CoreModule | |||||
| CoreModule, | |||||
| StoreModule.forRoot({shoppingList: shoppingListReducer}) | |||||
| ], | ], | ||||
| bootstrap: [AppComponent] | bootstrap: [AppComponent] | ||||
| }) | }) | ||||
| @@ -0,0 +1,12 @@ | |||||
| import { Action } from '@ngrx/store'; | |||||
| import { Ingredient } from '../../shared/ingredient.model'; | |||||
| export const ADD_INGREDIENT = 'ADD_INGREDIENT'; | |||||
| export class AddIngredient implements Action { | |||||
| readonly type = ADD_INGREDIENT; | |||||
| payload: Ingredient; | |||||
| } | |||||
| export type ShoppingListActions = AddIngredient; | |||||
| @@ -0,0 +1,23 @@ | |||||
| import * as ShoppingListActions from './shopping-list.actions'; | |||||
| import { Ingredient } from '../../shared/ingredient.model'; | |||||
| export const ADD_INGREDIENT = 'ADD_INGREDIENT'; | |||||
| const initialState = { | |||||
| ingredients: [ | |||||
| new Ingredient('Banana', 10) | |||||
| ] | |||||
| }; | |||||
| export function shoppingListReducer(state = initialState, action: ShoppingListActions.ShoppingListActions) { | |||||
| switch (action.type) { | |||||
| case ShoppingListActions.ADD_INGREDIENT: | |||||
| return { | |||||
| ...state, | |||||
| ingredients: [...state.ingredients, action.payload] | |||||
| }; | |||||
| default: | |||||
| return state; | |||||
| } | |||||
| } | |||||
| @@ -6,7 +6,7 @@ | |||||
| <a | <a | ||||
| class="list-group-item" | class="list-group-item" | ||||
| style="cursor: pointer;" | style="cursor: pointer;" | ||||
| *ngFor="let ingredient of ingredients; let i = index" | |||||
| *ngFor="let ingredient of (shoppingListState | async).ingredients; let i = index" | |||||
| (click)="onEditItem(i)" | (click)="onEditItem(i)" | ||||
| > | > | ||||
| {{ ingredient.name }} ({{ ingredient.amount }}) | {{ ingredient.name }} ({{ ingredient.amount }}) | ||||
| @@ -1,8 +1,10 @@ | |||||
| import { Component, OnInit } from '@angular/core'; | |||||
| import { Component, OnInit, OnDestroy } from '@angular/core'; | |||||
| import { Subscription } from 'rxjs/Subscription'; | |||||
| import { Store } from '@ngrx/store'; | |||||
| import { Observable } from 'rxjs/Observable'; | |||||
| import { Ingredient } from '../shared/ingredient.model'; | import { Ingredient } from '../shared/ingredient.model'; | ||||
| import { ShoppingListService } from './shopping-list.service'; | import { ShoppingListService } from './shopping-list.service'; | ||||
| import { Subscription } from 'rxjs/Subscription'; | |||||
| import { OnDestroy } from '@angular/core/src/metadata/lifecycle_hooks'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-shopping-list', | selector: 'app-shopping-list', | ||||
| @@ -10,18 +12,19 @@ import { OnDestroy } from '@angular/core/src/metadata/lifecycle_hooks'; | |||||
| styleUrls: ['./shopping-list.component.css'] | styleUrls: ['./shopping-list.component.css'] | ||||
| }) | }) | ||||
| export class ShoppingListComponent implements OnInit, OnDestroy { | export class ShoppingListComponent implements OnInit, OnDestroy { | ||||
| ingredients: Ingredient[]; | |||||
| shoppingListState: Observable<{ingredients: Ingredient[]}>; | |||||
| private subscription: Subscription | private subscription: Subscription | ||||
| constructor(private shoppingListService: ShoppingListService) { } | |||||
| constructor(private shoppingListService: ShoppingListService, | |||||
| private store: Store<{shoppingList: {ingredients: Ingredient[]}}>) { } | |||||
| ngOnInit() { | ngOnInit() { | ||||
| this.ingredients = this.shoppingListService.getIngredients(); | |||||
| this.subscription = this.shoppingListService.ingredientsChanged.subscribe( | |||||
| (ingredients: Ingredient[]) => { | |||||
| this.ingredients = ingredients; | |||||
| } | |||||
| ); | |||||
| this.shoppingListState = this.store.select('shoppingList'); | |||||
| // this.subscription = this.shoppingListService.ingredientsChanged.subscribe( | |||||
| // (ingredients: Ingredient[]) => { | |||||
| // this.ingredients = ingredients; | |||||
| // } | |||||
| // ); | |||||
| } | } | ||||
| onEditItem(index: number) { | onEditItem(index: number) { | ||||