25

Backbone.jsを使用して、このアプリの状態を追跡しようとしています。

ここに画像の説明を入力してください

デフォルトのセットを持つ「ChartAppModel」があります。

ChartAppModel = Backbone.Model.extend({

defaults: { 
    countries : [], 
    selectedCountries : [],
    year : 1970,
},

initialize: function() { 
    loadAbunchOfData();
    checkStartState();
}

});

ただし、開始フラグメントが指定されている場合、このデフォルト状態は上書きする必要があります。

var startState = $.deparam.fragment(); //using Ben Alman's BBQ plugin
this.set({selectedCountries: startState.s, year: startState.y});

これで、たとえばSidebarViewを更新する準備が整いました。

ChartAppViewSidebar = Backbone.View.extend({

initialize: function(){
      this.model.bind("change:selectedCountries", this.render);
},

render : function(){
      [... render new sidebar with check boxes ...]
},

問題は、モデルを更新するイベントハンドラーもサイドバーにあることです。

events: {
"change input[name=country]": "menuChangeHandler",
},

menuChangeHandler : function(){
      [... set selectedCountries on model ...]
},

したがって、フィードバックループが発生します...そして、新しい状態をプッシュする方法も必要です。モデルの変更を聞きます。

ChartAppModel = Backbone.Model.extend({

initialize: function() { 
    this.bind("change", this.setState);
}

});

...そして比較的すぐにこの状態管理者は崩壊するでしょう...

質問:

1)フラグメントに基づいてビュー(たとえば、「どのチェックボックスをオンにする必要があるか」)を初期化するにはどうすればよいですか?(一般的な「ルート」ではない状態/開始状態のベストプラクティスに関するヒントをいただければ幸いです)

2)ビューが自分でリッスンしているモデルに属性を設定しないようにするにはどうすればよいですか?

3)モデルの一部に基づいて新しい状態をプッシュするにはどうすればよいですか?

ボーナス:)

4)説明されているアプリのコードをどのようにレイアウトしますか?

ありがとう!

4

2 に答える 2

15

これは明確に定義された質問の1つです。

モデルとは何かという疑問があります。バックボーンの世界でモデルを構成するものについては、浮かんでいる定義があると思いますが、あなたの戦略がその定義に沿っているかどうかはわかりません。また、URLとモデルの両方に状態を保存しています。これから説明するように、状態をURLに保存するだけです。

これを行うと、2つのビューがあります。1つはアプリコントロール用で、もう1つはグラフ用にネストされています:GraphViewとAppView。モデルは、インターフェイスの状態ではなく、プロットするデータになります。

コントローラーを使用して、アプリビューをキックスタートし、URLで定義されたインターフェイス状態を処理します。

バックボーンの状態のレバーについての質問があります。従来のWebアプリケーションは、状態の主要な手段としてリンク/ URLを使用していましたが、現在はすべてが変化しています。考えられる戦略の1つは次のとおりです。

Checkbox Change Event -> Update location fragment -> trigger route in controller -> update the view
Slider Change Event -> Update location fragment -> trigger route in controller -> update the view

このような戦略の優れている点は、URLが渡されたりブックマークされたりする場合に対応できることです。

Url specified in address bar -> trigger route in controller -> update the view

擬似コードの例を見てみましょう。このために、データについていくつかの仮定を行います。データは、時間の経過に伴う犬の個体数(年の粒度)であり、スライダーには下限と上限が必要であり、ボリュームデータが大きすぎてすべてをロードできません。一度にクライアントに。

まず、統計データを表すモデルを見てみましょう。グラフの各ポイントには、{人口:27000、年:2003}のようなものが必要です。これを次のように表します。

DogStatModel extends Backbone.Model ->

このデータのコレクションは

DogStatCollection extends Backbone.Collection ->
    model: DogStatModel
    query: null // query sent to server to limit results
    url: function() {
        return "/dogStats?"+this.query
    }

次に、コントローラーを見てみましょう。私が提案するこの戦略では、コントローラーはその名に恥じないものです。

AppController extends Backbone.Controller ->
    dogStatCollection: null,
    appView: null,

    routes: {
         "/:query" : "showChart"
    },

    chart: function(query){
        // 2dani, you described a nice way in your question
        // but will be more complicated if selections are not mutually exclusive
        // countries you could have as countries=sweden;france&fullscreen=true
        queryMap = parse(query) //  
        if (!this.dogStatCollection) dogStatCollection = new DogStatCollection
        dogStatCollection.query = queryMap.serverQuery
        if (!this.appView) {
           appView = new AppView()
           appView.collection = dogStatCollection
        }
        appView.fullScreen = queryMap.fullScreen
        dogStatCollection.fetch(success:function(){
          appView.render()
        })            
    }
于 2011-05-25T17:02:27.970 に答える
2

2)ビューが自分でリッスンしているモデルに属性を設定しないようにするにはどうすればよいですか?

あなたはそうしない。モデルは、更新しようとするすべての属性に対して検証を実行する必要があります。これにより、属性の設定が失敗した場合や検証によって値が変更された場合にビューがリッスンする必要があります。

ビューが行うことは、モデルに値を設定しようとし、モデルが値を設定するか、データを変更して設定するか、拒否するかです。それに応じてビューを更新する必要があります。

3)モデルの一部に基づいて新しい状態をプッシュするにはどうすればよいですか?

// for each attribute
_.each(["attribute1", "attribute2", "attribute3", ...], _.bind(function(val) {
    // bind the change
    // bind the setState with `this` and the `value` as the first parameter
    this.bind("change:" + value, _.bind(this.setState, this, value));
}, this));
于 2011-05-25T16:20:09.560 に答える