0

获取后从服务器接收的 JSON 数据与我的视图同步时遇到问题。

我没有“mainmodel”的集合,因为我一次只使用一个“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 not a function”。啊。

所以现在,如果我将 FIRST 渲染函数更改为,将 at(i) 更改为 [i]

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

并将第二个渲染函数(移除 toJSON)更改为:

    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 格式问题,但现在我不知道。服务器将内容作为“应用程序/json”返回。

编辑: v1、v2、v3 的 JSON 值正确呈现。

有任何想法吗?

4

1 回答 1

3

你有两个问题:一个你知道,一个你不知道。

您知道的问题是您mainmodel不会自动将v4JSON 转换为集合,因此您最终会得到一个期望集合的数组。您可以通过将 a 添加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对象由模型的所有实例共享。此外,Backbone 将对defaults您的新模型进行浅拷贝。因此,如果您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 回答