骨干视图不适用于获取的json

时间:2012-10-24 03:53:48

标签: javascript json backbone.js

我遇到了在获取后将从服务器收到的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格式问题,但现在我不知道。服务器将内容返回为'application / json'。

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

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

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

您知道的问题是,您的mainmodel不会自动将v4 JSON转换为集合,因此您最终会得到一个阵列,您希望收集该集合。您可以通过向mainmodel添加parse来解决此问题:

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

您不知道的问题是defaults中的mainmodel有隐藏的引用分享问题:

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()
        };
    }
});