javascript – 使用MVC / Backbone.js实现复合模式

我的webapp具有复合结构,即每个类别集合可以包含单个项目和其他类别的混合作为其行/节点/子项(在此不确定正确的术语).实际上,它比这个简单一点,因为每个集合都是由一个模型“类别”表示的,所以基本上每个类别集合都有Item模型和Category模型作为其子项.

一般来说,这是使用MVC实现这种结构的一种可取的方法吗?更具体地说,在Backbone.js中,一个集合有可能拥有一个模型工厂(采用json并根据json的结构计算要生成的模型)而不是静态模型属性

解决方法

我假设您收到的 JSON类别/项目列表看起来像这样…
{
    'id': 1,'name': 'My 1st Category','children': [
        {
            'id': 2,'name': 'My 2nd Category','children': []
        },{
            'id': 1,'name': 'An Item','price': 109.99
        }
    ]
}

Backbone.js没有任何支持集合中多个模型的开箱即用的东西,但它也不会对您放在集合中的模型类型有任何限制.

在集合定义中指定模型类型只做一件事,它让Backbone知道要将原始JSON传递给集合而不是Backbone.Model对象时要创建的模型类型.如果您将Item模型添加到已经包含几个类别模型的集合中,则Backbone将弹出模型列表中没有问题;它不进行任何类型检查.

所以考虑到这一点,你可以使用集合提供的所有东西,除了传递原始的JSON;你需要自己处理.所以你的选择是预先建立你的模型,使它们成为Backbone.Model对象,或创建一些可以为你解析的东西.

对于第二个选项,解析器我建议将特殊变量传递给包含原始JSON的集合,然后在初始化函数中处理该变量.以下是一个例子:

var CategoryCollection = Backbone.Collection.extend({
    initialize: function(m,models) {
        _.each(models,function(model) {
            var modelObject = null;
            if (model.price !== undefined) {
                modelObject = new Item(model);
            } else {
                modelObject = new Category(model);
            }

            this.add(modelObject);
        },this);
    }
});

所以这有点黑客,但是您可以根据具体的字段(我的示例中的价格)来确定模型的类型,创建模型对象,然后将其添加到集合中.

你会这样称呼:

var myCollection = new CategoryCollection([],myJSON);

注意,你必须传递一个空数组作为第一个参数,因为这是你通常将一组模型传递给集合.

稍后在使用集合时,您可以使用简单的instanceof检查来确定是否处理项目或类别:

_.each(myCollection.models,function(model) {
    if (model instanceof Item) {
        console.log("It's an Item! Price: ",model.get("price"));
    } else {
        console.log("It's a Category!");
    }
});

相关文章

事件冒泡和事件捕获 起因:今天在封装一个bind函数的时候,发现el.addEventListener函数支持第三个参数...
js小数运算会出现精度问题 js number类型 JS 数字类型只有number类型,number类型相当于其他强类型语言...
什么是跨域 跨域 : 广义的跨域包含一下内容 : 1.资源跳转(链接跳转,重定向跳转,表单提交) 2.资源...
@ "TOC" 常见对base64的认知(不完全正确) 首先对base64常见的认知,也是须知的必须有...
搞懂:MVVM模式和Vue中的MVVM模式 MVVM MVVM : 的缩写,说都能直接说出来 :模型, :视图, :视图模...
首先我们需要一个html代码的框架如下: 我们的目的是实现ul中的内容进行横向的一点一点滚动。ul中的内容...