如何在 angular5 应用程序中显示来自 redux 商店的项目?
How to display items from redux store in angular5 app?
我有一个 angular5 组件,我正在尝试与 reduxstore 连接,它看起来像这样:
import { Component } from '@angular/core';
import { NgRedux, select, DevToolsExtension } from '@angular-redux/store';
import { TodoActions } from './actions';
import { AppState, INITIAL_STATE, rootReducer } from './store';
import {Observable} from "rxjs/Observable";
@Component({
selector: 'app-root',
template: `
<input type="text" #edit />
<button (click)="actions.add({data:edit,action:'ADD'})">add</button>
<p>The list is:</p>
<ul>
<li *ngFor="let item of (items | async)">
{{item}}
</li>
</ul>
`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
@select() readonly items$: Observable<string[]>;
constructor(
ngRedux: NgRedux<AppState>,
devTools: DevToolsExtension,
private actions: TodoActions) {
ngRedux.configureStore(
rootReducer,
INITIAL_STATE,
null,
devTools.isEnabled() ? [ devTools.enhancer() ] : []);
}
}
问题是我无法在列表中显示项目。这是 rootreducer:
import {Action} from 'redux';
import {TodoActions} from './actions';
export interface AppState {
items: string[];
}
export const INITIAL_STATE: AppState = {items: []};
export function rootReducer(state: AppState, action: Action): AppState {
switch (action.type) {
case TodoActions.ADD:
var newstate = state;
newstate.items.push(action.data.data.value);
return newstate;
}
;
default:
return state;
}
}
如何显示项目?看起来第一项从 redux-console 添加到状态。这里还有一个githublink
这看起来不太正确:
var newstate = state;
newstate.items.push(action.data.data.value);
return newstate;
你实际上并没有创建一个新数组或副本:newstate
和 state
都是同一个数组,所以你最好返回一个浅克隆的新数组:
export function rootReducer(state: AppState, action): AppState {
switch (action.type) {
case TodoActions.ADD:
return {
...state,
items: [
...state.items,
action.data.value
]
}
default:
return state;
}
}
您可能会注意到我已经取消了类型说明符 action
。我不确定将 Action
指定为操作类型是否有意义,在我见过的大多数示例代码中,它都是无类型传递的,因此:
export function rootReducer(state: AppState, action): AppState {
这将避免 TS 抱怨 Action
类型缺少 data
。或者,您可以为您编写的每个 reducer 定义一个自定义操作类型。
一旦你通过了它,我认为你看不到任何项目的原因是因为你在 @select
装饰器中将数组命名为 items$
。所以:
@Component({
selector: 'app-root',
template: `
<input type="text" #edit />
<button (click)="actions.add({value:edit.value,action:'ADD'})">add</button>
<p>The list is:</p>
<ul>
<li *ngFor="let item of (items$ | async)">
{{item}}
</li>
</ul>
`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
@select() readonly items$: Observable<string[]>;
效果更好。请注意,我稍微调整了按钮定义以避免传递整个输入,因为您只需要 value
.
我有一个 angular5 组件,我正在尝试与 reduxstore 连接,它看起来像这样:
import { Component } from '@angular/core';
import { NgRedux, select, DevToolsExtension } from '@angular-redux/store';
import { TodoActions } from './actions';
import { AppState, INITIAL_STATE, rootReducer } from './store';
import {Observable} from "rxjs/Observable";
@Component({
selector: 'app-root',
template: `
<input type="text" #edit />
<button (click)="actions.add({data:edit,action:'ADD'})">add</button>
<p>The list is:</p>
<ul>
<li *ngFor="let item of (items | async)">
{{item}}
</li>
</ul>
`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
@select() readonly items$: Observable<string[]>;
constructor(
ngRedux: NgRedux<AppState>,
devTools: DevToolsExtension,
private actions: TodoActions) {
ngRedux.configureStore(
rootReducer,
INITIAL_STATE,
null,
devTools.isEnabled() ? [ devTools.enhancer() ] : []);
}
}
问题是我无法在列表中显示项目。这是 rootreducer:
import {Action} from 'redux';
import {TodoActions} from './actions';
export interface AppState {
items: string[];
}
export const INITIAL_STATE: AppState = {items: []};
export function rootReducer(state: AppState, action: Action): AppState {
switch (action.type) {
case TodoActions.ADD:
var newstate = state;
newstate.items.push(action.data.data.value);
return newstate;
}
;
default:
return state;
}
}
如何显示项目?看起来第一项从 redux-console 添加到状态。这里还有一个githublink
这看起来不太正确:
var newstate = state;
newstate.items.push(action.data.data.value);
return newstate;
你实际上并没有创建一个新数组或副本:newstate
和 state
都是同一个数组,所以你最好返回一个浅克隆的新数组:
export function rootReducer(state: AppState, action): AppState {
switch (action.type) {
case TodoActions.ADD:
return {
...state,
items: [
...state.items,
action.data.value
]
}
default:
return state;
}
}
您可能会注意到我已经取消了类型说明符 action
。我不确定将 Action
指定为操作类型是否有意义,在我见过的大多数示例代码中,它都是无类型传递的,因此:
export function rootReducer(state: AppState, action): AppState {
这将避免 TS 抱怨 Action
类型缺少 data
。或者,您可以为您编写的每个 reducer 定义一个自定义操作类型。
一旦你通过了它,我认为你看不到任何项目的原因是因为你在 @select
装饰器中将数组命名为 items$
。所以:
@Component({
selector: 'app-root',
template: `
<input type="text" #edit />
<button (click)="actions.add({value:edit.value,action:'ADD'})">add</button>
<p>The list is:</p>
<ul>
<li *ngFor="let item of (items$ | async)">
{{item}}
</li>
</ul>
`,
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app';
@select() readonly items$: Observable<string[]>;
效果更好。请注意,我稍微调整了按钮定义以避免传递整个输入,因为您只需要 value
.