骨干中的嵌套模型.js,如何接近或者,在 JS 中

2022-08-30 05:11:25

我从服务器提供了以下JSON。有了这个,我想创建一个具有嵌套模型的模型。我不确定这是实现这一目标的方法。

//json
[{
    name : "example",
    layout : {
        x : 100,
        y : 100,
    }
}]

我希望将它们转换为具有以下结构的两个嵌套主干模型:

// structure
Image
    Layout
...

因此,我像这样定义布局模型:

var Layout = Backbone.Model.extend({});

但是,我应该使用以下两种(如果有的话)技术中的哪一种来定义图像模型?A或B以下?

一个

var Image = Backbone.Model.extend({
    initialize: function() {
        this.set({ 'layout' : new Layout(this.get('layout')) })
    }
});

或 B

var Image = Backbone.Model.extend({
    initialize: function() {
        this.layout = new Layout( this.get('layout') );
    }
});

答案 1

我在编写Backbone应用程序时遇到了同样的问题。必须处理嵌入式/嵌套模型。我做了一些调整,我认为这是一个非常优雅的解决方案。

是的,您可以修改 parse 方法来更改对象中的属性,但所有这些实际上都是非常不可维护的代码 IMO,感觉更像是一个黑客而不是一个解决方案。

以下是我对您的示例的建议:

首先像这样定义布局模型。

var layoutModel = Backbone.Model.extend({});

然后这是您的图像模型:

var imageModel = Backbone.Model.extend({

    model: {
        layout: layoutModel,
    },

    parse: function(response){
        for(var key in this.model)
        {
            var embeddedClass = this.model[key];
            var embeddedData = response[key];
            response[key] = new embeddedClass(embeddedData, {parse:true});
        }
        return response;
    }
});

请注意,我没有篡改模型本身,而只是从解析方法中传回所需的对象。

这应该确保从服务器读取时嵌套模型的结构。现在,您会注意到此处实际上不处理保存或设置,因为我认为使用正确的模型显式设置嵌套模型是有意义的。

这样:

image.set({layout : new Layout({x: 100, y: 100})})

另请注意,您实际上是通过调用以下调用嵌套模型中的解析方法:

new embeddedClass(embeddedData, {parse:true});

您可以根据需要在现场定义任意数量的嵌套模型。model

当然,如果你想把嵌套模型保存在它自己的表中。这还不够。但是在将对象作为一个整体读取和保存的情况下,此解决方案应该就足够了。


答案 2

我发布此代码作为Peter Lyon建议重新定义解析的示例。我有同样的问题,这对我有用(使用Rails后端)。此代码是用咖啡脚本编写的。我为不熟悉它的人做了一些明确的事情。

class AppName.Collections.PostsCollection extends Backbone.Collection
  model: AppName.Models.Post

  url: '/posts'

  ...

  # parse: redefined to allow for nested models
  parse: (response) ->  # function definition
     # convert each comment attribute into a CommentsCollection
    if _.isArray response
      _.each response, (obj) ->
        obj.comments = new AppName.Collections.CommentsCollection obj.comments
    else
      response.comments = new AppName.Collections.CommentsCollection response.comments

    return response

或者,在 JS 中

parse: function(response) {
  if (_.isArray(response)) {
    return _.each(response, function(obj) {
      return obj.comments = new AppName.Collections.CommentsCollection(obj.comments);
    });
  } else {
    response.comments = new AppName.Collections.CommentsCollection(response.comments);
  }
  return response;
};