2012-05-18 11 views
13

テンプレートからモデル(backbone.js)で実装した計算フィールドにアクセスしたいと思います。 これを行うにはヘルパーを定義する必要がありますか?ハンドルバーテンプレートからバックボーンモデルの計算フィールドにアクセスする方法は?

私はテンプレートにモデルを渡す方法と問題が関係していると思います。 this.model.toJSON()を渡すと、プロパティにはアクセスできますが、定義した関数にはアクセスできません。 this.modelを直接渡すと、関数にアクセスできますが、バックボーンモデルのプロパティにはアクセスできません。

+0

私は、問題は、私はテンプレートにモデルを渡す方法で行うことがあると思います。 – Juanma

答えて

17

常にthis.model.toJSON()をテンプレートに渡します。

計算された値を得るために必要なことは、モデル上のtoJSONメソッドを上書きすることです。


MyModel = Backbone.Model.extend({ 

    myValue: function(){ 
    return "this is a calculated value"; 
    }, 

    toJSON: function(){ 
    // get the standard json for the object 
    var json = Backbone.Model.prototype.toJSON.apply(this, arguments); 

    // get the calculated value 
    json.myValue = this.myValue(); 

    // send it all back 
    return json; 
    } 

}) 

そして今、あなたはビューでそれへのアクセスを持っていることを意味しtoJSONによって返されるJSONからmyValueへのアクセス権を持っています。

もう1つのオプションは、ヘルパーメソッドを作成してHandlebarsで登録することです。テンプレートのレンダリング方法やテンプレートに渡されるデータに基づいて変更される機能がない限り、私はそれを気にしません。

+10

'toJSON'をオーバーライドすることには欠点があります:' Backbone.sync'は 'toJSON'を使ってモデルをシリアライズします(正確に' sync'は 'toJSON'を呼び出す' JSON.stringify'を呼び出します)。これでサーバは 'myValueそれはおそらくそれを気にしなくても。これは問題である場合とそうでない場合があります。 –

+0

ありがとうございます。 – Juanma

0

私は同じ問題がありました。 @DerickBaileyは当然ですが、toSSONをオーバーライドすることは仕事です。しかし、それはサーバーとの通信にも漏れる(彼の答えに対するmuuのコメントを参照)。

最終的に、テンプレートへのデータのエクスポートを特に処理するためのバックボーンプラグインを構築しました。これは最小限の手間をかけて行います:Backbone.Marionette.Export。また、ネストされた構造を扱い、循環参照を処理します。docsを参照してください。

これはどのように動作するのですか。プロジェクトにプラグインファイルをインクルードし、

MyModel = Backbone.Model.extend({ 

    foo: function() { 
     return "I am a calculated value"; 
    }, 

    exportable: "foo" // <-- this is the one line you have to add 

}); 

を宣言あなたはマリオネットユーザであれば、あなたはすでにこの時点で行われます。モデル属性のようにfooがテンプレートに表示されます。

単純なバックボーンビューでは、レンダリング時にtoJSONの代わりにmyModel.export()またはmyCollection.export()を呼び出してください。

引数を取るメソッドについては、onExportハンドラがあります。例は、docsにあります。

-1

それを行うための最善の方法は、あなたのモデルにこれを追加することです:

function initialize() { 
    this.set("calculatedColumn", function() { return this.otherColumn; }); 
} 

バックボーンモデルは、通常、「model.attributes」内部で実際のデータ値を格納します。そのため、モデルをテンプレートに直接渡すと、モデルに直接追加された機能だけがあり、データは追加されません。また、model.toJSON()を使用すると、通常、バックボーンで_.clone(model.attributes)として実装されます(backbone.jsを参照)。したがって、モデルに直接追加された関数ではなく、データがあります。これが上記の理由です - モデルオブジェクト自体ではなく、model.attributesに関数を設定します。 model.attributesを直接参照しないでください。model.get( "calculatedColumn")とmodel.set( "calculatedColumn"、...)を使用してください。

だからモデル。get( "calculatedColumn")は関数を返します。ハンドルバーで{{computedColumn}}に行くと(ハンドルバーを使用していると仮定して)、関数によって返された値が表示されます。しかし、バックボーンはmodel.toJSONへのJSON.stringify(backbone.js)を行い、JSON.stringifyは関数を無視するため、calculateColumnはサーバーに送信されません。 JSON.stringifyが関数を無視しないようにするには(ビューのレンダリングとモデルの同期中にtoJSONがモデル上で実行されるたびに関数がデータ値に変換されるようにする)@Derick Baileyと同様にmodel.toJSONをオーバーライドします。

また、Backbone.Modelから独自のBaseModelを派生させ、.toJSONをオーバーライドし、必要に応じてすべてのモデルをBaseModelから派生させることができます。その後、任意のモデルに適用できるジェネリックバージョンの.toJSONが必要になります。ここで

4

は別の可能性がある:(モデルから初期化)

initialize: function() { 
     this.on("change", function() { 
      this.set({ calculatedColumn: this.get("otherColumn") }, { silent: true }); 
     }); 
    }, 

Computed properties in Backbone

関連する問題