浏览代码

24-314 Moving data logic to NgRx, removing shopping list service

ngrx
Nils Dittberner 8 年前
父节点
当前提交
569a9da503
共有 8 个文件被更改,包括 122 次插入64 次删除
  1. +0
    -2
      src/app/core/core.module.ts
  2. +6
    -2
      src/app/recipes/recipe-detail/recipe-detail.component.ts
  3. +3
    -11
      src/app/recipes/recipe.service.ts
  4. +34
    -1
      src/app/shopping-list/ngrx/shopping-list.actions.ts
  5. +58
    -2
      src/app/shopping-list/ngrx/shopping-list.reducers.ts
  6. +17
    -15
      src/app/shopping-list/shopping-edit/shopping-edit.component.ts
  7. +4
    -4
      src/app/shopping-list/shopping-list.component.ts
  8. +0
    -27
      src/app/shopping-list/shopping-list.service.ts

+ 0
- 2
src/app/core/core.module.ts 查看文件

@@ -5,7 +5,6 @@ import { HeaderComponent } from "./header/header.component";
import { HomeComponent } from "./home/home.component";
import { SharedModule } from "../shared/shared.module";
import { AppRoutingModule } from "../app-routing.module";
import { ShoppingListService } from "../shopping-list/shopping-list.service";
import { RecipeService } from "../recipes/recipe.service";
import { DataStorageService } from "../shared/data-storage.service";
import { AuthService } from "../auth/auth.service";
@@ -26,7 +25,6 @@ import { LoggingInterceptor } from "../shared/logging.interceptor";
HeaderComponent
],
providers: [
ShoppingListService,
RecipeService,
DataStorageService,
AuthService,


+ 6
- 2
src/app/recipes/recipe-detail/recipe-detail.component.ts 查看文件

@@ -1,8 +1,11 @@
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, Params } from '@angular/router';
import { Store } from '@ngrx/store';

import { Recipe } from '../recipe.model';
import { RecipeService } from '../recipe.service';
import * as ShoppingListActions from '../../shopping-list/ngrx/shopping-list.actions';
import * as fromShoppingList from '../../shopping-list/ngrx/shopping-list.reducers';

@Component({
selector: 'app-recipe-detail',
@@ -15,7 +18,8 @@ export class RecipeDetailComponent implements OnInit {
constructor(private recipeService: RecipeService,
private route: ActivatedRoute,
private router: Router) { }
private router: Router,
private store: Store<fromShoppingList.AppState>) { }

ngOnInit() {
this.route.params.subscribe(
@@ -27,7 +31,7 @@ export class RecipeDetailComponent implements OnInit {
}

onAddToShoppingList() {
this.recipeService.addIngredientsToShoppingList(this.recipe.ingredients);
this.store.dispatch(new ShoppingListActions.AddIngredients(this.recipe.ingredients));
}

onEditRecipe() {


+ 3
- 11
src/app/recipes/recipe.service.ts 查看文件

@@ -1,17 +1,13 @@
import { EventEmitter } from "@angular/core";
import { Subject } from "rxjs/Subject";

import { Recipe } from "./recipe.model";
import { EventEmitter, Injectable } from "@angular/core";
import { Ingredient } from "../shared/ingredient.model";
import { ShoppingListService } from "../shopping-list/shopping-list.service";
import { Subject } from "rxjs/Subject";
import { nextTick } from "q";

@Injectable()
export class RecipeService {
recipesChanged = new Subject<Recipe[]>();
private recipes: Recipe[] = [];

constructor(private shoppingListService: ShoppingListService) { }

replaceRecipes(recipes: Recipe[]) {
this.recipes = recipes;
this.recipesChanged.next(this.recipes.slice());
@@ -25,10 +21,6 @@ export class RecipeService {
return this.recipes[index];
}

addIngredientsToShoppingList(ingredients: Ingredient[]) {
this.shoppingListService.addIngredients(ingredients);
}

addRecipe(recipe: Recipe) {
this.recipes.push(recipe);
this.recipesChanged.next(this.recipes.slice());


+ 34
- 1
src/app/shopping-list/ngrx/shopping-list.actions.ts 查看文件

@@ -3,6 +3,11 @@ import { Action } from '@ngrx/store';
import { Ingredient } from '../../shared/ingredient.model';

export const ADD_INGREDIENT = 'ADD_INGREDIENT';
export const ADD_INGREDIENTS = 'ADD_INGREDIENTS';
export const UPDATE_INGREDIENT = 'UPDATE_INGREDIENT';
export const DELETE_INGREDIENT = 'DELETE_INGREDIENT';
export const START_EDIT = 'START_EDIT';
export const STOP_EDIT = 'STOP_EDIT';

export class AddIngredient implements Action {
readonly type = ADD_INGREDIENT;
@@ -10,4 +15,32 @@ export class AddIngredient implements Action {
constructor(public payload: Ingredient) {}
}

export type ShoppingListActions = AddIngredient;
export class AddIngredients implements Action {
readonly type = ADD_INGREDIENTS;
constructor(public payload: Ingredient[]) {}
}

export class UpdateIngredient implements Action {
readonly type = UPDATE_INGREDIENT;
constructor(public payload: Ingredient) {}
}

export class DeleteIngredient implements Action {
readonly type = DELETE_INGREDIENT;
}

export class StartEdit implements Action {
readonly type = START_EDIT;
constructor(public payload: number) {}
}

export class StopEdit implements Action {
readonly type = STOP_EDIT;
}



export type ShoppingListActions = AddIngredient | AddIngredients | UpdateIngredient | DeleteIngredient | StartEdit | StopEdit;

+ 58
- 2
src/app/shopping-list/ngrx/shopping-list.reducers.ts 查看文件

@@ -2,12 +2,27 @@ import * as ShoppingListActions from './shopping-list.actions';

import { Ingredient } from '../../shared/ingredient.model';

export interface AppState {
shoppingList: State
}

export interface State {
ingredients: Ingredient[];
editedIngredient: Ingredient;
editedIngredientIndex: number;
}

export const ADD_INGREDIENT = 'ADD_INGREDIENT';
export const ADD_INGREDIENTS = 'ADD_INGREDIENTS';
export const UPDATE_INGREDIENT = 'UPDATE_INGREDIENT';
export const DELETE_INGREDIENT = 'DELETE_INGREDIENT';

const initialState = {
const initialState: State = {
ingredients: [
new Ingredient('Banana', 10)
]
],
editedIngredient: null,
editedIngredientIndex: -1
};

export function shoppingListReducer(state = initialState, action: ShoppingListActions.ShoppingListActions) {
@@ -17,6 +32,47 @@ export function shoppingListReducer(state = initialState, action: ShoppingListAc
...state,
ingredients: [...state.ingredients, action.payload]
};
case ShoppingListActions.ADD_INGREDIENTS:
return {
...state,
ingredients: [...state.ingredients, ...action.payload]
};
case ShoppingListActions.UPDATE_INGREDIENT:
const ingredient = state.ingredients[state.editedIngredientIndex];
const updatedIngredient = {
...ingredient,
...action.payload
}
const ingredients = [...state.ingredients];
ingredients[state.editedIngredientIndex] = updatedIngredient;
return {
...state,
ingredients: ingredients,
editedIngredient: null,
editedIngredientIndex: -1
};
case ShoppingListActions.DELETE_INGREDIENT:
const oldIngredients = [...state.ingredients];
oldIngredients.splice(state.editedIngredientIndex, 1);
return {
...state,
ingredients: oldIngredients,
editedIngredient: null,
editedIngredientIndex: -1
};
case ShoppingListActions.START_EDIT:
const editedIngredient = {...state.ingredients[action.payload]};
return {
...state,
editedIngredient: editedIngredient,
editedIngredientIndex: action.payload
}
case ShoppingListActions.STOP_EDIT:
return {
...state,
editedIngredient: null,
editedIngredientIndex: -1
}
default:
return state;
}

+ 17
- 15
src/app/shopping-list/shopping-edit/shopping-edit.component.ts 查看文件

@@ -4,8 +4,8 @@ import { Subscription } from 'rxjs/Subscription';
import { Store } from '@ngrx/store';

import { Ingredient } from '../../shared/ingredient.model';
import { ShoppingListService } from '../shopping-list.service';
import * as ShoppingListActions from '../ngrx/shopping-list.actions';
import * as fromShoppingList from '../ngrx/shopping-list.reducers';

@Component({
selector: 'app-shopping-edit',
@@ -16,22 +16,23 @@ export class ShoppingEditComponent implements OnInit, OnDestroy {
@ViewChild('f') shoppingListForm: NgForm;
subscription: Subscription
editMode = false;
editedItemIndex: number;
editedItem: Ingredient;

constructor(private shoppingListService: ShoppingListService,
private store: Store<{shoppingList: {ingredients: Ingredient[]}}>) { }
constructor(private store: Store<fromShoppingList.AppState>) { }

ngOnInit() {
this.subscription = this.shoppingListService.startedEditing.subscribe(
(index: number) => {
this.editedItemIndex = index;
this.editMode = true;
this.editedItem = this.shoppingListService.getIngredient(index);
this.shoppingListForm.setValue({
name: this.editedItem.name,
amount: this.editedItem.amount
})
this.subscription = this.store.select('shoppingList').subscribe(
data => {
if (data.editedIngredientIndex > -1) {
this.editedItem = data.editedIngredient;
this.editMode = true;
this.shoppingListForm.setValue({
name: this.editedItem.name,
amount: this.editedItem.amount
})
} else {
this.editMode = false;
}
}
);
}
@@ -40,7 +41,7 @@ export class ShoppingEditComponent implements OnInit, OnDestroy {
const value = form.value
const newIngredient = new Ingredient(value.name, value.amount);
if (this.editMode) {
this.shoppingListService.updateIngredient(this.editedItemIndex, newIngredient);
this.store.dispatch(new ShoppingListActions.UpdateIngredient(newIngredient));
} else {
this.store.dispatch(new ShoppingListActions.AddIngredient(newIngredient));
}
@@ -54,11 +55,12 @@ export class ShoppingEditComponent implements OnInit, OnDestroy {
}

onDelete() {
this.shoppingListService.deleteIngredient(this.editedItemIndex);
this.store.dispatch(new ShoppingListActions.DeleteIngredient());
this.onClear();
}

ngOnDestroy() {
this.store.dispatch(new ShoppingListActions.StopEdit());
this.subscription.unsubscribe();
}
}

+ 4
- 4
src/app/shopping-list/shopping-list.component.ts 查看文件

@@ -3,7 +3,8 @@ import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';

import { Ingredient } from '../shared/ingredient.model';
import { ShoppingListService } from './shopping-list.service';
import * as ShoppingListActions from './ngrx/shopping-list.actions';
import * as fromShoppingList from './ngrx/shopping-list.reducers';

@Component({
selector: 'app-shopping-list',
@@ -13,14 +14,13 @@ import { ShoppingListService } from './shopping-list.service';
export class ShoppingListComponent implements OnInit {
shoppingListState: Observable<{ingredients: Ingredient[]}>;

constructor(private shoppingListService: ShoppingListService,
private store: Store<{shoppingList: {ingredients: Ingredient[]}}>) { }
constructor(private store: Store<fromShoppingList.AppState>) { }

ngOnInit() {
this.shoppingListState = this.store.select('shoppingList');
}

onEditItem(index: number) {
this.shoppingListService.startedEditing.next(index);
this.store.dispatch(new ShoppingListActions.StartEdit(index));
}
}

+ 0
- 27
src/app/shopping-list/shopping-list.service.ts 查看文件

@@ -1,27 +0,0 @@
import { Ingredient } from "../shared/ingredient.model";
import { Subject } from "rxjs/Subject";

export class ShoppingListService {
ingredientsChanged = new Subject<Ingredient[]>();
startedEditing = new Subject<number>();
private ingredients: Ingredient[] = [];
getIngredient(index: number) {
return this.ingredients[index];
}

addIngredients(ingredients: Ingredient[]) {
this.ingredients.push(...ingredients);
this.ingredientsChanged.next(this.ingredients.slice());
}

updateIngredient(index: number, newIngredient: Ingredient) {
this.ingredients[index] = newIngredient;
this.ingredientsChanged.next(this.ingredients.slice());
}

deleteIngredient(index: number) {
this.ingredients.splice(index, 1);
this.ingredientsChanged.next(this.ingredients.slice());
}
}

正在加载...
取消
保存