2015-12-26 18 views

答えて

3

を私はアイテムを保存、sortKeyおよびsortKind(asc/desc)をReduxストアで使用します。

Angularコンポーネント(私はReactと同じであると信じています)では、Observableとしてストア状態を取得して、アイテムsortKeyとsortOrderをUXに表示できます。

ユーザがソートキー(順序)を変更するためにテーブルの列をクリックすると、新しいキー/ソート順が状態のレデューサーにディスパッチされます。

レデューサーは新しい並べ替えを実行し、更新された値で新しい状態を返します。

このようにコンポーネントのObservableは、UXを更新するイベントを発生させます。

利点:

  • ユーザーがブラウザを更新した場合の状態でSORTKEYとsortKindを保存することで、部品

  • 外のロジックをソートキープ、あなたは(私が使用して正確UXを復元することができますRedux-LocalStorage to sync)

  • ストアにはソートされたアイテムがあるため、ユーザーが積極的にソートを実行するときにのみソートを実行します。

  • ソートされた項目は、ユーザーがコンポーネントに戻るときに記憶されます。

マイ減速(「bizzesは」私の項目のリストである、と私はアイテムを格納するのにImmutable.Listを使用)

import { List }      from 'immutable'; 
import { IBizz, IBizzState } from './bizz.types'; 
import { BIZZES_SET, BIZZES_SORT} from 'store/constants'; 

const SORT_ASC = 'asc'; 
const SORT_DESC = 'desc'; 

const defaultSortKey = 'serialNo'; 
const defaultSortOrder = SORT_ASC; 

const INITIAL_STATE: IBizzState = { 
    bizzes: List([]), 
    sortKey: defaultSortKey, 
    sortOrder: defaultSortOrder 
}; 

export function bizzReducer(state: IBizzState = INITIAL_STATE, action: any): IBizzState { 

    switch (action.type) { 

     case BIZZES_SET: 
      return { 
       bizzes: List(action.payload.bizzes), 
       sortKey: action.payload.sortKey || defaultSortKey, 
       sortOrder: action.payload.sortOrder || defaultSortOrder 
      }; 

     case BIZZES_SORT: 
      let sortKey = action.payload.sortKey || defaultSortKey; 

      if(sortKey === state.sortKey) { 
       state.sortOrder = state.sortOrder === SORT_ASC ? SORT_DESC : SORT_ASC; 
      } 

      return { 
       bizzes: List(state.bizzes.sort((a, b) => { 
        if(a[sortKey] < b[sortKey]) return state.sortOrder === SORT_ASC ? -1 : 1; 
        if(a[sortKey] > b[sortKey]) return state.sortOrder === SORT_ASC ? 1: -1; 
        return 0; 
       })), 
       sortKey: sortKey, 
       sortOrder: state.sortOrder 
      }; 
     default: return state; 
    } 
} 

そして、私のコンポーネント(私はなどの店舗を取得するにはNG2-Reduxのを使用観測):あなたが見ることができるように

import { Component, OnInit, OnDestroy, ChangeDetectionStrategy } from '@angular/core'; 
import { select } from 'store'; 
import { BizzActions } from 'actions/index'; 

@Component({ 
    selector: 'bizzlist', 
    templateUrl: './bizz-list.html', 
    changeDetection: ChangeDetectionStrategy.OnPush 
}) 
export class BizzListComponent implements OnInit { 


    @select([ 'bizzState']) bizzState$; 

    public sortOrder: string; 
    public sortKey: string; 
    public bizzes = []; 
    private bizzStateSubscription; 


    constructor( 
     public bizzActions: BizzActions 
    ) { } 

    ngOnInit() { 
     this.bizzStateSubscription = this.bizzState$.subscribe(bizzState => { 
      this.bizzes = bizzState.bizzes; 
      this.sortKey = bizzState.sortKey; 
      this.sortOrder = bizzState.sortOrder; 
     }); 
    } 

    ngOnDestroy() { 
     this.bizzStateSubscription.unsubscribe(); 
    } 



    public sortBizzes(key) { 
     this.bizzActions.sortBizzes(key); 
    } 
} 

、私は実際のReduxの派遣を行うためにBizzActionsと呼ばれるアクションを()を使用しています。あなたはあなたのコンポーネントでそれを行うことができますが、私はこれらのものを分離することを好みます。良い測定のために、ここで私のBizzActions(サービス)です:

import { Injectable }   from '@angular/core'; 
import { NgRedux, IAppState } from 'store'; 
import { 
    BIZZES_SET, 
    BIZZES_SORT 
} from 'store/constants'; 

@Injectable() 
export class BizzActions { 

    constructor (private ngRedux: NgRedux<IAppState>) {} 

    public setBizzes = (bizzes: any) => { 
     return this.ngRedux.dispatch({ 
      type: BIZZES_SET, 
      payload: { 
       bizzes: bizzes 
      } 
     }); 
    }; 

    public sortBizzes = (key:string) => { 
     return this.ngRedux.dispatch({ 
      type: BIZZES_SORT, 
      payload: { 
       sortKey: key 
      } 
     }); 
    }; 

} 
8

-ing @connectあなたはReduxのストアでコンポーネントに反応するときに、データを並べ替えることができます:

function mapStateToProps(state) { 
    var items = state.items.slice(0); 
    items.sort() 
    return { 
    items: items 
    } 
} 

@connect(mapStoreToProps) 
class MyComponent extends React.Component { 
    render() { 
     var items = this.props.items; 
    } 
} 

Reduxのドキュメントは、藤堂の例では同様のケースを示しています。http://rackt.org/redux/docs/basics/UsageWithReact.html

+4

これは簡単で洗練された解決策ですが、** **状態変更ごとに実行されます:\ – Denis

+1

状態からの引数が実際に変更されたときにセレクタ結果を再計算するだけで、すべての状態変更をソートすることはできません。そこにはいくつかの図書館があり、これを行うことができます。また、あなたはreduxを正しく使っている限り(つまり、あなたのレデューサーは純粋です)、自分で書くことはかなり簡単です。 [再選択](https://github.com/reactjs/reselect#q-are-there-typescript-typings)を見てください。 –

1

私は、セクションの辞書パターンを使用して、私の減速をソートしてきました。言い換えれば、私は、ヘッダで私の項目を並べ替える日付を言って、その後、日付キーによって、配列内のオブジェクトを格納します。

sectionHeaders: ["Monday", "Tuesday"], 
dict:{ 
    Monday: [{obj1},{obj2},{obj3}], 
    Tuesday: [{obj4}], 
} 

ListViewの点を除いますので、その後、私は私のListViewコントロールを移入するためにネイティブリアクトでこの辞書を使いますcloneWithRowsAndSectionsメソッドを使用してセクションを持つアイテムをレンダリングするこのオブジェクト形式。

私の並べ替えが簡単ではないので、これはパフォーマンスの最適化です。私は深い比較をしなければなりません、そして、この方法では、最初に店を作るときに一度しか行いません。

私はまた、IDで辞書を使用し、実際のオブジェクトの代わりにソートされたdictにIDだけを格納して遊んだことがあります。

更新はより複雑で、項目がセクションから削除された場合、セクションヘッダーを削除する時期を決定する必要があります。

5

IMOの場合、データをソートする適切な場所はレデューサーに直接はなく、セレクタです。 Reduxのドキュメントから

Computing Derived Data

再選択は、メモ化、構成可能なセレクタ関数を作成するためのシンプルなライブラリです。 Reselectセレクタは、Reduxストアから派生データを効率的に計算するために使用できます。

私は現在データのフィルタリングとソートにセレクタを使用しています。

  1. 状態でデータが繰り返し表示されません。特定の方法でソートされたアイテムのコピーを保存する必要はありません。
  2. 異なるコンポーネントで同じデータを使用することができます。それぞれのコンポーネントは、異なるソート機能を使用してソートします。
  3. セレクタを組み合わせるには、すでにアプリケーションに含まれているセレクタを使用して、多くのデータ計算を適用します。
  4. あなたが正しいとすれば、セレクタは純粋な関数となり、簡単にテストすることができます。
  5. 多くのコンポーネントで同じセレクタを使用します。
+0

はい、セレクタは間違いなく洗練されたソリューションです – tech4242

関連する問題