2017-12-01 12 views
2

NxワークスペースにAngular 5と@ ngrx/storeを使用してエンタープライズアプリケーションを作成しています。@ ngrx/storeで同じ状態の複数のバージョンをIDで保存するにはどうすればよいですか?

私たちのアプリケーションの要件の1つは、複数のタブを開くことをサポートすることです。つまり、サイドメニューから、複数の機能または同じ機能を選択し、アプリケーション内の別々のタブで開くことができます。ユーザーは、完全に別々の複数のタブで同じタイプの検索を開くことができるため、これらのタブの状態を分離できる必要があります。たとえば、アカウント検索タブを開き、アカウントID 123456で検索し、別のアカウント検索タブで234567で検索します。明らかに、あるタブの状態を別のタブと競合させたくありません。

私はこれに対する最良のアプローチが何であるかはわかりません。私たちのアカウントの検索サブ機能の例状態は

のlibs /アカウント/ SRC /検索/ +状態/ search.reducer.ts

export interface AccountSearchState { 
    accounts: { [id: string]: Account }; 
    metadata: Metadata; 
    ids: string[]; 
    loading: boolean; 
    query: AccountQuery; 
    ... 
} 

それはその上にトップレベルの機能の状態を持っているようなものになるだろう、のように:私は考えることができる

のlibs /アカウント/ SRC/+状態/ index.ts

export interface AccountState { 
    search: fromSearch.AccountSearchState 
    ... 
} 

一つの解決策は、タブIDの下で上記のサブ機能の状態を保存することです。

のlibs /アカウント/ SRC /検索/ +状態/ search.reducer.ts

export interface AccountSearchState { 
    states: { [id: string]: SubState } 
} 

のlibs /アカウント/ SRC/+状態/ index.ts

export interface AccountState { 
    search: fromSearch.AccountSearchState 
    tab: fromTabs.TabState 
    ... 
} 

...これでしょう当社の機能モジュールのすべてで使用することができる別のTabStateを必要とし、最低でもこの含まれます

のlibs /タブ/ SRC/+状態/ index.tsを

export interface TabState { 
    selectedId: string; 
} 

その後、我々はこれらの状態の両方使用するセレクタを作成できます、私たちのユーザーが別のタブをクリックすると

のlibs /アカウント/ SRC/+状態/ index.ts

export const getAccountState = createFeatureSelector<AccountState>('account'); 

export const getTabState = createSelector(getAccountState, (state: AccountState) => state.tab); 

export const getAccountSearchState = createSelector(getAccountState, (state: AccountState) => state.search); 

export const getAccounts = createSelector(getTabState, getAccountSearchState, (tab, search) => search.states[tab.selectedId].accounts); 

を選択されたタブIDを変更するイベントを出さなければなりません。タブIDを処理する必要があるのは、各機能のタブ縮小機能を使用して、現在のタブを認識できるように機能状態を更新することです。これは、私たちのすべての機能に対して、この種の構造を持つ必要があることを意味します。私は何とかそれを何とか抽象化したいときです。私はそれを達成するために他にどのようにしているのか分かりません。選択したタブIDを各フィーチャストアに保存する必要はありません。代わりにルート状態になりますが、その値をフィーチャステートに渡して適切な値を返す方法が完全にはわかりませんデータ。

誰もがこれに対するより良いアプローチのための指針を持っていますか?

おかげで、

ダン

答えて

0

は、私の考えは、タブ内のコンポーネントは、他のタブが存在するかどうかを気にせず、そのスライスを注入できるように、タブコンポーネントは、その子孫に店の独自のスライスを提供することです。

私のコード例は、それを使用しますので、私は、(私が書いた)ng-app-state経由ngrx/storeでの作業に慣れているが、それはあなたがそれなしで同じ概念を使用することができるはずngrx/store単なるラッパーです。

@Injectable() 
export class TabStore extends AppStore<TabState> implements OnDestroy { 
    constructor(store: Store<any>) { 
    super(store, uniqueId('tabState'), new TabState()); 
    } 

    ngOnDestroy() { 
    this.delete(); // when the tab is destroyed, clean up the store 
    } 
} 

@Component({providers: [TabStore]}) 
export class TabComponent { 
    constructor(tabStore: TabStore) { 
    // tabStore holds state that is unique to me 
    } 
} 

@Component() 
export class ChildOfTabComponent { 
    constructor(tabStore: TabStore) { 
    // I can also access the same store from descendants 
    } 
} 

uniqueId各タブの状態のための独自のルートレベルの鍵を生成するだけの方法があります。 underscorelodash、私の場合はmicro-dashですが、タブごとに固有のキーを生成する方法は問題ありません。

関連する問題