

Backbone.js と Backbone.Marionette の組み合わせで、以下のようなコードを書いています。

[code]

    var Model = Backbone.Model.extend({
        url: '任意のURL',
    
        dataFetch: function() {
            this.fetch()
                .fail(alert('error!!'));
        }
    });
    
    var ViewItem = Marionette.ViewItem.extend({
        model: new Model();
        modelEvents: {
            'sync': 'displayModelAttr'
        },
    
        initialize: function() {
            this.model.dataFetch();
        },
    
        displayModelAttr: function() {
            console.log(this.model.attributes);
        }
    });
    
    var viewItem = new ViewItem();
    
[/code]

`model` で発火した `sync` イベントで拾い、 `model` の `attributes` をコンソールに表示しています。  
しかしながら指定した url から `fetch` した値ではなく、空の Object が表示されてしまいます。  
`sync` イベントが発火した時点で、 `model` は `fetch` した結果を自身に `set`
していると考えていたのですが、まず、その認識から誤っているのでしょうか。

通信そのものは正常に成功しており、期待したjsonが返却されていることをブラウザの開発ツールで確認しております。


CC BY-SA 3.0
2015-01-21T13:43:30.717
5010
2015-01-22T02:56:29.410
2015-01-22T02:56:29.410
7214
5827
question
javascript jquery backbone.js marionette
Backbone.Model で sync イベントが発火したとき、期待する値が set されていない


問題が再現できないので関係あるか不明ですが、`Marionette.ItemView.extend` で model を を指定するかわりに、`new
ViewItem({model: new Model()})` のようにコンストラクタで model を指定するようにしてみてはいかがでしょうか?

元のコードだと、すべての ViewItem で 1 つの model を共有してしまっているために、期待しない挙動になっているのかもしれません。

下記のコードで試したところ、期待通り、サーバから取得した値が表示されました。  
質問中のコードからの変更箇所はコメントで示しています。

[code]

    var Model = Backbone.Model.extend({
        url: "/model.json",
        dataFetch: function() {
            this.fetch()
                .fail(function() { alert('error!!') }); // fail に関数を渡すよう変更
        }
    });
    
    var ViewItem = Marionette.ItemView.extend({ // Marionette.ViewItem -> Marionette.ItemView
        // ここで model を指定するとすべての ViewItem で 1 つの model が共有されてしまう
        // コンストラクタに model を渡すよう変更する
        // model: new Model(),
        modelEvents: {
            'sync': 'displayModelAttr'
        },
    
        initialize: function() {
            this.model.dataFetch();
        },
    
        displayModelAttr: function() {
            console.log(this.model.attributes);
        }
    });
    
    var viewItem = new ViewItem({model: new Model()}); // ViewItem ごとに異なる model を渡す
    
[/code]

検証環境:

  * jQuery 2.1.3
  * Underscore 1.6.0
  * Backbone 1.1.2
  * Marionette 2.3.1
  * Chrome 39


CC BY-SA 3.0
2015-01-22T02:34:46.643
5027
2015-01-22T02:34:46.643
5789
5010
answer