2017-08-16 77 views
0

总的来说Redux noob在这里,我有点困难从我的视图中获取我的数据用于商店。这里是我的操作,减速等如何从ngrx商店中获取值到我的模板中?

genre.model.ts

export interface Genre { 
    id: string; 
    title: string; 
    description: string; 
    slug: string; 
    error: string; 
} 

export const initialState: Genre = { 
    id: '', 
    title: '', 
    description: '', 
    slug: '', 
    error: null 
}; 

genre.service.ts

import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import { Http } from '@angular/http'; 
import {environment} from "../../../environments/environment"; 
import {Genre} from "./genre.model"; 

@Injectable() 
export class GenreService { 

    apiUrl = environment.apiUrl + environment.apiVersion + '/'; 

    constructor(private http: Http) { } 

    /** 
    * Gets Genres 
    * 
    * @returns {Observable<Genre[]>} 
    */ 
    getGenres(): Observable<Genre[]> { 
     return this.http.get(this.apiUrl + 'genres/') 
      .map(res => res.json()); 
    } 

    /** 
    * Gets an individual genre 
    * 
    * @param {String} slug 
    * @returns {Observable<Genre[]>} 
    */ 
    getGenre(slug: String): Observable<Genre[]> { 
     return this.http.get(this.apiUrl + 'genres/' + slug) 
      .map(res => res.json().genre); 
    } 
} 

genre.actions.ts

import { Action } from '@ngrx/store'; 
import { Injectable } from '@angular/core'; 

import { Genre } from '../_shared/genre.model'; 

@Injectable() 
export class GenreActions { 

    static LOAD_GENRES = '[Genre] Load Genres'; 
    loadGenres(): Action { 
     return { 
      type: GenreActions.LOAD_GENRES 
     }; 
    } 

    static LOAD_GENRES_SUCCESS = '[Genre] Load Genres Success'; 
    loadGenresSuccess(genres): Action { 
     return { 
      type: GenreActions.LOAD_GENRES_SUCCESS, 
      payload: genres 
     }; 
    } 

    static GET_GENRE = '[Genre] Get Genre'; 
    getGenre(slug): Action { 
     return { 
      type: GenreActions.GET_GENRE, 
      payload: slug 
     }; 
    } 

    static GET_GENRE_SUCCESS = '[Genre] Get Genre Success'; 
    getGenreSuccess(genre): Action { 
     return { 
      type: GenreActions.GET_GENRE_SUCCESS, 
      payload: genre 
     }; 
    } 
} 

genre.reducers.ts

import { Action } from '@ngrx/store'; 

import {Genre, initialState} from '../_shared/genre.model'; 

import { GenreActions } from './genre.actions'; 

export function genreReducer(state: Genre = initialState, action: Action) { 
    switch (action.type) { 
     case GenreActions.GET_GENRE_SUCCESS: { 
      return action.payload; 
     } 
     case GenreActions.LOAD_GENRES_SUCCESS: { 
      return action.payload; 
     } 
     default: { 
      return state; 
     } 
    } 
} 

genre.effects.ts

export class GenreEffects { 
    constructor (
     private update$: Actions, 
     private genreActions: GenreActions, 
     private svc: GenreService, 
    ) {} 

    @Effect() loadGenres$ = this.update$ 
     .ofType(GenreActions.LOAD_GENRES) 
     .switchMap(() => this.svc.getGenres()) 
     .map(genres => this.genreActions.loadGenresSuccess(genres)); 

    @Effect() getGenre$ = this.update$ 
     .ofType(GenreActions.GET_GENRE) 
     .map(action => action.payload) 
     .switchMap(slug => this.svc.getGenre(slug)) 
     .map(genre => this.genreActions.getGenreSuccess(genre)); 
} 

genre.detail.component.ts

import { Store } from '@ngrx/store'; 
import { Observable } from 'rxjs/Observable'; 
import { Subscription } from 'rxjs/Subscription'; 
import { ActivatedRoute, Router } from '@angular/router'; 
import { Component, OnInit } from '@angular/core'; 

import { Genre } from '../_shared/genre.model'; 
import { GenreActions } from '../_store/genre.actions'; 

@Component({ 
    selector: 'app-genre-detail', 
    templateUrl: './genre-detail.component.html', 
    styleUrls: ['./genre-detail.component.scss'] 
}) 
export class GenreDetailComponent implements OnInit { 

    public idSub: Subscription; 
    public genre: Observable<any>; 

    constructor(
     private store: Store<Genre>, 
     private route: ActivatedRoute, 
     private genreActions: GenreActions, 
     private router: Router 
    ) { 
     this.genre = store.select('genres'); 
    } 

    ngOnInit() { 
     this.idSub = this.route.params.subscribe(params => { 
      this.store.dispatch(this.genreActions.getGenre(params['slug'])); 
      console.log(this.genre); 
      }); 
    } 
} 

我可以看到,我的API请求正在被解雇,这是返回数据,我可以在Re中看到dux devtools状态正在填充,但我似乎无法使用正常的{{ genre.title }}获取数据并转到我的视图中,我只是将[Object object]丢回给我了?

我相信,这可能会是一件很容易的,但就像我说我是一个总的小白和花了围绕这家5小时,试图不同的东西以下不同的教程等

Console

+0

什么是您正在使用的ngrx版本? –

+0

另外,当你使用效果器时,它是一个异步调用,你需要在选择器中进行订阅。像'select('流派')。订阅(数据=>数据)' –

+0

ngrx商店版本2.2。2 – ChrisBratherton

回答

3

我我猜你的流派是一个阵列列表

它应该是这样的一些东西把它当作线框。

genre : any ; 

ngOnInit(){ 
this.idSub = this.route.params.subscribe(params => { 
    this.store.dispatch(this.genreActions.getGenre(params['slug'])); 
    }); 
    this.store.select('genres').subscribe(data => this.genre = data) 
} 

如果你想看着这个link

我只是挖了我的混帐,你可以检查我的使用NGRX V2的回购本快照NGRX 4的样子。我DONOT有一个工作示例为相同的,但放心代码workes LINK

UPDATE

做出不同的对象类型使用类型接口状态现在

export interface AppState { 
    genre:Genre 
} 

订阅此构造函数中的状态对象类型或ngOnInit

private store: Store<AppState>, 
private route: ActivatedRoute, 
private genreActions: GenreActions, 
private router: Router 
) { 
this.store.select('genre').subscribe(data => this.genre = data); 
} 
+0

谢谢,我得到的是怎么回事的JIST在你的例子中,我的外表几乎完全相同。我相信这是ngrx/effects返回结果的方式。我用类型替换项目(从你的例子),我仍然得到同样的问题,如果我在ngInit控制台登录this.genre然后我的STORE对象回到我的控制台。 – ChrisBratherton

+0

可以打印结果存储到它如何为正在添加您 –

+0

更新了截图:) – ChrisBratherton