0

サーバーから受信したJSONデータをフェッチ後にビューと同期する際に問題が発生します。

「mainmodel」のコレクションはありません。一度に1つの「mainmodel」だけを操作しているのですが、とにかく多数の「mymodel」を操作しているため、構造は次のようになります。

    var mymodel = Backbone.Model.extend({
        defaults: {k1:"",
                   k2:"",
                   k3:""}
    });

    var collection = Backbone.Collection.extend({model:mymodel,});

    var mainmodel = Backbone.Model.extend({
        defaults: {v1:"",
                   v2:"",
                   v3:"",
                   v4:new collection()
    });

親ビューのレンダリング関数から「mymodel」のネストされたビューを作成します。これは機能します...、新しいモデルで作業している場合のみです。

// My ParentView render function
render: function() {
for (var i = 0; i < this.model.v4.length;i++) {
    var view = new MyModelView({model:this.model.v4.at(i)});
    this.$el.append($(view.render().el));
}
this.$el.append(this.template(this.model.toJSON()));
return this;
},

// The MyModelView render function below 
render: function() {
    this.$el.html(this.template(this.model.toJSON()));
return this;
},

これで、アプリケーションを開いてそこからモデルを作成すると、上記が機能します。ただし、アプリを開いてIDを指定すると、サーバーにフェッチしてデータを取得し、新しいParentViewを作成すると、「this.model.v4.atは関数ではありません」というエラーが表示されます。うーん。

したがって、FIRSTレンダリング関数をに変更すると、at(i)が[i]に変更されます。

    var view = new MyModelView({model:this.model.v4[i]});

そして、toJSONを削除して、2番目のレンダリング関数を次のように変更します。

    this.$el.html(this.template(this.model)); 

レンダリングします。しかし、それでもエラーなしでビューを移動することはできません。当然のことです。console.log(JSON.stringify(this.model));を使用しました。それらがparentViewとMyModelViewに到着すると。返されるJSONは、フェッチされたか作成されたかに関係なく、次のようになります。

    {"v1":"val1",
     "v2":"val2,
     "v3":"val3",
     "v4":[{"k1":"key1","k2":"key2","k3","key"}, { ... }, { ... }]
    }

JSONデータ構造は同じように見えます。JSON形式が正しくないと思ったので、モデルをビューに渡す前にJSON.parseを使用してみましたが、うまくいきませんでした。少し離れているかもしれませんが、もともとはJSON形式の問題があると思っていましたが、今はわかりません。サーバーはコンテンツを「application/json」として返します。

編集:v1、v2、v3のJSON値は正しくレンダリングされます。

何か案は?

4

1 に答える 1

3

あなたには2つの問題があります。1つは知っていること、もう1つは知らないことです。

あなたが知っている問題は、JSONをコレクションにmainmodel自動的に変換しないv4ため、コレクションを期待している配列になってしまうことです。これを修正するには、:にを追加しparseます。mainmodel

parse: function(response) {
    if(response.v4)
        response.v4 = new collection(response.v4);
    return response;
}

あなたが知らない問題は、あなたのdefaultsinmainmodelに隠された参照共有の問題があるということです:

var mainmodel = Backbone.Model.extend({
    defaults: {
        //...
        v4: new collection()
    }
});

オブジェクトで定義したものはすべてBackbone.Model.extendモデルのプロトタイプに含まれるため、defaultsオブジェクト全体がモデルのすべてのインスタンスで共有されます。defaultsまた、Backboneは新しいモデルに浅いコピーを行います。したがって、あなたm1 = new mainmodel()m2 = new mainmodel()、の場合m1m2とはまったく同じv4属性を持ちます。これは、次の関数を使用して解決できますdefaults

var mainmodel = Backbone.Model.extend({
    defaults: function() {
        return {
            v1: '',
            v2: '',
            v3: '',
            v4: new collection()
        };
    }
});
于 2012-10-24T04:27:03.977 に答える