7

Ember.jsアプリのどこにインターフェース状態(永続化されたモデル状態ではなく)が存在するべきかについての公式の話はありますか?

ルーターのドキュメントの「ユーザーが開始したイベントへの応答」の部分には、クリックイベントを写真の「showPhoto」メソッドに委任する例がありますが、モデル「show」自体を持つことは、望ましくない懸念の混合のようです。

多くの場合、インターフェースの状態がURLで表され、ページを更新したりURLを誰かに送信したりすると復元されるように、状態をルーターに保存する必要があることを理解しています。しかし、ページで選択されたアイテムのリストなど、非階層状態についてはどうでしょうか。

理想的には、そのタイプの状態はクエリ/ハッシュパラメータとしてシリアル化されます(例:http ://www.hipmunk.com/flights/QSF-to-NYC#!dates = Sep15、Sep16p1; kind = Flight&locations = QSF、YYZ&dates = Sep15 、Sep23〜tab = 1)しかし、私が知る限り、ルーターはその機能を提供していませんね。

BackboneConfで、Jeremy Ashkenasは、Backboneでそれを行う正しい方法は、モデルにも状態を保存することであると述べました(彼は、「選択された」フィールドを持つモデルの例を持っていました)。しかし、トム・デールは、それは良い考えではなく、エンバーでどのように行われるべきかではないと言ったと思います。残念ながら、彼がそれをどのように行うべきかについて言及したことを覚えていません。

4

1 に答える 1

4

状態をルーティング可能(つまり、URLを介して到達可能)にする場合は、残り火のルーターを介してシリアル化および逆シリアル化できる必要があります。状態が一時的でルーティングできない場合は、おそらくコントローラーに保持するのが最適です。

複数のモデル間で複雑なインターフェイス状態を表す必要がある場合(たとえば、リスト内のアイテムを選択する場合)、基になるデータモデルをラップするオブジェクトのコントローラー固有の配列を維持することを検討してください。特にそれらのモデルが複数のビューで使用されている場合、モデルでビューステートを直接表すのはハックだと思います。

あなたが提供した例では、複雑なルートを接続するために次のようなことをするかもしれません:

Ember.Route.extend({
  route: "flights/:cities/dates/:dates",

  serialize: function(router, context){
    return {cities: context.get('cities'),
            dates:  context.get('dates')};
  },

  deserialize: function(router, params){
    // return a context object that will be passed into connectOutlets()
    return {cities: params.cities,
            dates:  params.dates};
  },

  connectOutlets: function(router, context) {
    // pass the context from deserialize() in as the content of a FlightController
    router.get('applicationController').connectOutlet('flight', context);
  }
})

「flights?cities =:cities&dates =:dates」などのルートを使用することもできますが、上記の方がおそらくよりクリーンでSEOに適していることに注意してください。


Gabrielのコメントの後に拡張:それぞれが独自のタブにある検索の配列を維持したい場合は、それらの検索のデータをアプリケーションレベルの配列(App.currentUser.activeSearchesなど)に保持することをお勧めします。私の考えでは、ユーザーがタブを切り替えるたびにこのデータを再作成する必要はありません。代わりに、ルーターはこのデータを取得しdeserialize()て、コンテキストとしてに渡しますconnectOutlets()。このデータを表すビューとコントローラーは、タブを切り替えるときにこのオブジェクトに基づいてすばやく再構築する必要があります。私の例を上から拡張しましょう:

Ember.Route.extend({
  route: "flights/:cities/dates/:dates",

  serialize: function(router, context){
    return {cities: context.get('cities'),
            dates:  context.get('dates')};
  },

  deserialize: function(router, params){
    // find or create a "Search" object that contains the filters and results,
    // which will be passed into connectOutlets()
    return App.currentUser.findOrCreateSearch({cities: params.cities,
                                               dates:  params.dates});
  },

  connectOutlets: function(router, context) {
    // pass the context (a search object) from deserialize() in as the content of a FlightController
    router.get('applicationController').connectOutlet('flight', context);
  }
})
于 2012-09-14T16:56:15.190 に答える