我试图弄清楚如何将许多资源状态组合成各种组件状态以及构成AppState的内容.大多数ngrx指南/示例只处理资源(例如书籍)或有限状态(例如书籍和选定的书籍),但我认为我没有遇到过比这更复杂的事情.
如果您有十几个资源,在多个需要不同资源状态的组件中有各种状态(列表,项目,搜索项,菜单项,过滤器等),您会怎么做?
我已经四处寻找,我提出了以下结构,但我不相信这是预期的:
AppState & reducer
<- combine reducers
- Component states & reducers
<- combine reducers
-- Resource states & reducers
Run Code Online (Sandbox Code Playgroud)
您可以将资源缩减器(例如bookReducer,booksReducer,bookSearchTitleReducer)组合到与组件相关的缩减器(例如bookSearchReducer)中,然后将所有组件缩减器组合到一个具有一个AppState的缩减器中,并在AppModule中将它与商店提供者一起使用.
这是要走的路还是有其他(正确的)方法呢?如果这是一个很好的方法,我会在Component构造函数中使用Store或Store吗?
[编辑]
好吧,ngrx-example-app确实处理了更多的组件,我看到它只在组件级创建状态,而不是在资源级创建状态,组合状态和各自的reducers并在组件构造函数中使用完整的状态对象:'store:商店'.
我想,因为它是一个官方的例子,这将是处理状态/减少器的预期方式.
[编辑]
新的v4 ngrx使用起来更简单,有更好的文档和示例应用程序来帮助你.以下内容主要与v2及其怪癖相关,后者在v4中不再是问题.
[作废]
经过大量的反复试验,我找到了一个好的,有效的配方.我将在这里分享它的要点,也许它会帮助某人.
减速器组成指南对我帮助很大,并说服我选择Resource> Component> App的原始状态/减速器结构.该指南太大,不适合这里,你可能会想要这里的最新版本.
这里有一个关于具有两个组件的应用程序的一些关键文件中我必须做的事情,包括两个基本资源(用户和资产)以及衍生物(列表)和参数(搜索).
store/reducers/user/index.ts:
import { ActionReducer, combineReducers } from '@ngrx/store';
import { authenticatedUserReducer } from './authenticatedUser.reducer';
import { selectedUserReducer } from './selectedUser.reducer';
import { userListReducer } from './userList.reducer';
import { userSearchReducer } from './userSearch.reducer';
import { User } from '../../models';
const reducers = {
authenticated: authenticatedUserReducer,
selected: selectedUserReducer,
list: userListReducer,
search: userSearchReducer
};
interface UserState {
authenticated: User,
selected: User,
list: User[],
search: string
}
const reducer: ActionReducer<UserState> = combineReducers(reducers);
function userReducer(state: any, action: any) {
return reducer(state, action);
}
export { userReducer, UserState };
Run Code Online (Sandbox Code Playgroud)
store/reducers/asset/index.ts:
import { ActionReducer, combineReducers } from '@ngrx/store';
import { selectedAssetReducer } from './selectedAsset.reducer';
import { assetListReducer } from './assetList.reducer';
import { assetSearchReducer } from './assetSearch.reducer';
import { Asset } from '../../models';
const reducers = {
selected: selectedAssetReducer,
list: assetListReducer,
search: assetSearchReducer
};
interface AssetState {
selected: Asset,
list: Asset[],
search: string
}
const reducer: ActionReducer<AssetState> = combineReducers(reducers);
function assetReducer(state: any, action: any) {
return reducer(state, action);
}
export { assetReducer, AssetState };
Run Code Online (Sandbox Code Playgroud)
store/reducers/index.ts:
import { routerReducer, RouterState } from '@ngrx/router-store';
import { userReducer, UserState } from './user';
import { assetReducer, AssetState } from './asset';
const reducers = {
router: routerReducer,
user: userReducer,
asset: assetReducer
};
interface AppState {
router: RouterState,
user: UserState,
asset: AssetState
}
export { reducers, AppState };
Run Code Online (Sandbox Code Playgroud)
注意:我还包括单独提供的路由器减速器.
app.module.ts:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';
import { StoreModule } from '@ngrx/store';
import { RouterStoreModule } from '@ngrx/router-store';
import { reducers } from './store';
import { AppComponent } from './app.component';
import { AppRoutes } from './app.routes';
import { HomeComponent } from './components/home/home.component';
@NgModule({
declarations: [
AppComponent,
HomeComponent
],
imports: [
BrowserModule,
FormsModule,
HttpModule,
RouterModule.forRoot(AppRoutes),
StoreModule.provideStore(reducers),
RouterStoreModule.connectRouter()
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)
注意:在此处使用您需要的内容,废弃您不需要的内容.我在/ store中创建了另一个index.ts文件,它将来导出redurs,所有模型以及其他一些东西.
home.component.ts:
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Store } from '@ngrx/store';
import { AppState, User } from '../../store';
@Component({
selector: 'home',
templateUrl: './home.template.html'
})
export class HomeComponent {
user: Observable<User>;
constructor (private store: Store<AppState>) {
this.user = store.select('user', 'selected');
store.dispatch({ type: 'SET_USER_NAME', payload: 'Jesse' });
store.dispatch({ type: 'ADD_USER_ROLE', payload: 'scientist' });
store.dispatch({ type: 'ADD_USER_ROLE', payload: 'wordsmith' });
}
}
Run Code Online (Sandbox Code Playgroud)
注意:您可以使用{{(user | async)?.name}}模板中的内容进行测试.
这就是它.可能有更好的方法,我知道我可以只用一个级别(例如只是基本资源),这完全取决于你认为最适合你的应用程序.
| 归档时间: |
|
| 查看次数: |
12667 次 |
| 最近记录: |