[英]How do I get the value from an ngrx store into my template?
A total Redux noob here, I am having a little difficulty getting my data out of the store for use within my view. 总的来说,这是Redux的新手,我在将数据移出商店以在视图中使用时遇到了一些困难。 Here are my Actions, Reducers etc. 这是我的动作,减速器等。
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 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);
});
}
}
I can see that my API request is being fired, and it is return data, I can see in the Redux devtools that state is being populated but I just can't seem to get the data out and in to my views using the normal {{ genre.title }}
I just get [Object object]
being thrown back at me? 我可以看到我的API请求已被触发,并且它是返回数据,我可以在Redux devtools中看到状态已被填充,但是我似乎无法使用普通的{{ genre.title }}
我只是把[Object object]
扔回我身边?
I am sure that this might be something really easy but like I said I am a total noob and have spent around 5 hours on this trying out different things following different tutorials etc. 我敢肯定,这可能真的很容易,但是就像我说的那样,我是一个菜鸟,花了大约5个小时来尝试按照不同的教程等进行不同的尝试。
I am guessing your genre is a list of array 我猜你的风格是数组的列表
It should be some thing like this take it as wireframe. 像这样的东西应该作为线框。
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)
}
If you want to look up to ngrx 4 look at this link 如果您想查看ngrx 4,请查看此链接
I just dug up my git you can check this snapshot of my repo of using ngrx v2 . 我只是挖了我的git,您可以检查我使用ngrx v2的仓库的快照。 I donot have a working example for the same but rest assured the code workes LINK 我没有相同的工作示例,但请放心代码可以正常工作LINK
UPDATE 更新
Make a different Object for Genre to use the Genre interface in state 为流派制作一个不同的对象,以在状态下使用流派接口
export interface AppState {
genre:Genre
}
Now Subscribe to this state object genre in the constructor or ngOnInit 现在在构造函数或ngOnInit中订阅此状态对象类型
private store: Store<AppState>,
private route: ActivatedRoute,
private genreActions: GenreActions,
private router: Router
) {
this.store.select('genre').subscribe(data => this.genre = data);
}
Currently, you are getting just the Observable but expecting the list of genre. 当前,您只获得Observable,但需要类型列表。 And, that is the problem. 而且,这就是问题所在。 You need to subscribe it to get the value. 您需要订阅以获得价值。
Make a different Object for Genre to use the Genre interface in state (as Rahul Singh told already) 为流派制作一个不同的对象,以在状态下使用流派接口(如Rahul Singh所述)
export interface AppState {
genre:Genre
}
constructor(private store: Store<AppState>,
private route: ActivatedRoute,
private genreActions: GenreActions,
private router: Router) {}
and in ngOnInit subscribe it to obeserve the change. 并在ngOnInit中订阅它以观察更改。
ngOnInit(): void {
this.store.select(s => s.genre).subscribe(data => this.genre = data);
}
Note : ngOnInit()
is used to make sure that the component's properties (for example: @Input() someId: number
) you used are already initialized . 注意 : ngOnInit()
用于确保您使用的组件属性(例如: @Input() someId: number
)已经初始化。 So, If you use any component properties you should do it in ngOnInit()
. 因此,如果您使用任何组件属性,则应在ngOnInit()
。 otherwise constructor()
is fine. 否则, constructor()
可以。 but we should use constructor()
to setup Dependency Injection and not much else. 但我们应该使用constructor()
来设置依赖注入,而不必过多设置。 ngOnInit()
is better place to "start" - it's where/when components' bindings are resolved. ngOnInit()
是“开始”的更好位置-解析组件绑定的位置/位置。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.