【问题标题】:Populate Backbone.js JSON response into nested collections inside nested collections/models将 Backbone.js JSON 响应填充到嵌套集合/模型中的嵌套集合中
【发布时间】:2015-12-07 23:59:03
【问题描述】:

我的问题是我刚开始使用 Backbone.js,并且无法解决一个复杂的问题。我想保存一个具有无限字段的表单,并且某些字段还需要具有无限选项。我只是担心我可能从错误的一端开始使用 JSON 响应,而不是先构建模型/集合。这是我尝试实现的简短伪代码。

id:
parent: <blockid>
fields: array(
  id:
  title:
  helpertext
  options: array(
    id:
    type:
    value:
  )
)

目前我正在处理来自服务器的伪造 JSON 响应,这是我从头开始构建的,现在我想在客户端将其划分为模型和集合。

//Fake a server response
var JSONresponse = {
    "formid":"1",
    "fields":[
        {
            "fieldid":"1",
            "title":"Empty title",
            "helper":"Helper text",
            "type":"radio",
            "options":[
                {
                    "optionid":"1",
                    "value":"Empty option.."
                },
                {
                    "optionid":"2",
                    "value":"Empty option.."
                }
            ]
        },
        {
            // fieldid2
        }
    ]
};

想法是添加我认为合适的字段,然后如果字段类型是 radio/checkbox/ul/ol,则字段中还必须有一个“选项”数组。

到目前为止我的工作:

    var app = {};
    app.Models = {};
    app.Collections = {};
    app.View = {};

    app.Models.Option = Backbone.Model.extend({
    });

    app.Collections.Options = Backbone.Collection.extend({
        model: app.Models.Option
    });

    app.Models.Field = Backbone.Model.extend({
        options: new app.Collections.Options()
    });

    app.Collections.Fields = Backbone.Collection.extend({
        model: app.Models.Field
    });

    app.Models.Form = Backbone.Model.extend({
        formid  : "1",
        fields: new app.Collections.Fields(),
        initialize: function() {
        }
    });

如何将我的 JSON 响应拆分为所有这些模型和集合? (也许我应该重新评估我的方法,并改用 form.fieldList 和 form.optionList[fieldListId] 之类的东西。如果是这样,那会是什么样子?)

编辑:经过多次修复,这里有一点jsfiddle,但我仍然不知道如何使内部选项列表工作。

【问题讨论】:

  • 一种选择是为您的 JSON 响应使用单个模型,并为与 JSON 的某些部分关联的每个模型/集合覆盖 Backbone 的 sync 方法。我不能为你做完整的实现,因为它太复杂了。例如,请参阅我的 JS tool where 这种方法用于解决与您类似的问题。
  • 感谢您的回复。但是,我并没有从那个链接中得到我想要的所有东西,也没有从你的解释中得到。我确实采用了单一模型 JSON 的想法,所以我觉得我离解决方案越来越近了。不过,我可能以错误的方式开始,我试图重现一个 JSON。最好从头开始创造你想要的东西,而不是从房子的屋顶开始。 :)

标签: javascript json backbone.js collections underscore.js


【解决方案1】:

在普通 Backbone 中处理嵌套模型和集合的情况非常困难。

最简单的处理方式是这样的:

   var Option = Nested.Model.extend({
       idAttribute : 'optionid',

       defaults : {
          optionid : Integer
          value : ""
       }
    });

    var Field = Nested.Model.extend({
        idAttribute : 'fieldid',

        defaults : {
          fieldid : Integer,

          title : "",
          helper : "",
          type : "radio",
          options : Option.Collection
        }
    });

    var Form = Nested.Model.extend({
        idAttribute : 'formid',

        defaults : {
          formid: Integer,
          fields: Field.Collection
    });

https://github.com/Volicon/backbone.nestedTypes

就是这样。是的,您可以直接访问属性作为免费奖励,只需form.fields.first().options.first().value,没有getset 垃圾。

【讨论】:

    【解决方案2】:

    最简单的解决方案是使用Backbone RelationalBackbone Associations

    文档应该足以帮助您入门。

    如果您不想使用库,可以覆盖 Form 模型上的 parse 函数。

    app.Models.Form = Backbone.Model.extend({
        defaults: {
            fields: new app.Collections.Fields()
        },
    
        parse: function(response, options) {
            return {
                formid: response.formid,
                fields: new app.Collections.Fields(_.map(response.fields, function(field) {
                    if (field.options) {
                        field.options = new app.Collections.Options(field.options);
                    }
    
                    return field;
                }))
            };
        }
    });
    

    现在,如果您从服务器获取表单,响应将被解析为模型和集合的对象图。

    form.get('fields') 将返回一个 app.Collections.Fields 集合。 form.get('fields').first().get('options') 将返回一个 app.Collections.Options 集合(如果存在任何选项)。

    另外,您可以像这样创建表单模型:

    var form = new app.Models.Form(JSONresponse, {
        parse: true
    });
    

    这将导致相同的对象结构。

    【讨论】:

    • 我宁愿在没有额外插件的情况下这样做。肯定有可能吗?
    • 谢谢,我在寻求答案的过程中偶然发现了类似的解决方案,但尚未对其进行测试。不过我有信心,所以我把你的答案标记为正确的。 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-27
    • 2013-10-04
    • 1970-01-01
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    相关资源
    最近更新 更多