演员/初始化骨干模型子模型(Cast/initialize submodels of a Backb

2019-06-28 02:34发布

我想我有一个非常简单的问题,这只是相当困难的字,因此很难找到一个解决方案。 建立:

  • PathCollection是路径的Backbone.Collection
  • 路径是Backbone.Model含有NodeCollection(这是一个Backbone.Collection)和EdgeCollection(这是一个Backbone.Collection)。

当我取PathCollection

paths = new PathCollection()
paths.fetch()

显然,路径实例化。 不过,我错过了那个地方,我可以允许的路径从属性哈希实例及其子模型。 我真的不能使用解析,对不对? 基本上即时寻找切入点模型时其实例化,并与属性进行设置。 我觉得一定是有约定的。

Answer 1:

所以我写了一对夫妇使用与答案parse()set()实例化和填充子模型和子集(嵌套数据)。 但是,我还没有看到整合的一些做法,很多我见过一个真正全面的答案。 我倾向于逛了一下,当我写了很多,所以我可能离题一点点,但这个或许对人们通过类似类型的问题将会是有益的。

有几个方法可以做到这一点。 使用parse()就是其中之一。 操纵set()是另一回事。 在这些实例initialize()是另外一个。 这样做的路径模型的所有外部另一个(例如path = new Path(); path.nodes = new NodeCollection();等)

第二个考虑是这样的。 你想要的节点和边缘的集合是模型的属性? 或者模特属性?

哦,这么多的选择。 很多自由,但有时(我们沮丧)的它使得它更难以确定“正确的方式”。

由于这种经常出现,我会做一个很长的帖子,并通过一个经过其中之一。 所以忍耐一下,因为我继续更新这个答案。

做模型之外-简单而直接的

这通常是添加嵌套模式和集合时,你只需要在某个特定的模型或集合的简单方法。

path = new PathModel();

path.nodes = new NodeCollection();
path.edge = new EdgeCollection();

// Continue to set up the nested data URL, etc.

这是最简单的方式和效果很好,当你处理一个时间模型和集合不需要有一个定义。 虽然你可以很容易产生某种方法(例如,查看方法)这些模型与它做任何事情之前构造该对象。

使用initialize()在每一个模型子模型/收藏

如果你知道某个模型的每个实例将永远有一个子模型或子集,来设置的东西,将利用最简单的方法initialize()函数。

例如,把你的路径模式:

Path = Backbone.Model.extend({
    initialize: function() {
        this.nodes = new NodeCollection();
        this.paths = new PathCollection();

        // Maybe assign a proper url in relation to this Path model
        // You might even set up a change:id listener to set the url when this
        // model gets an id, assuming it doesn't have one at start.
        this.nodes.url = this.id ? 'path/' + this.id + '/nodes' : undefined;
        this.paths.url = this.id ? 'path/' + this.id + '/paths' : undefined;
    }
});

现在你的子集可以获取像path.nodes.fetch()它会传递到正确的URL。 十分简单。

使用parse()实例化和设置子数据

也许,就有点比较麻烦,如果你不想承担每一个模型都将有一个节点和边缘的集合。 也许你想嵌套模型/收藏品仅在fetch()传回这些数据。 这是用案例parse()就可以派上用场。

用的东西parse()是,它需要的任何JSON的服务器响应,并能正确命名空间,并把它传递给模型前处理它set()函数。 因此,我们可以检查是否包含一个模型或收集的原始数据,减少到父模型属性响应之前处理它。

例如,也许从我们的服务器,我们得到这样的回应:

// Path model JSON example with nested collections JSON arrays
{
    'name':'orange site',
    'url':'orange.com',
    'nodes':[
        {'id':'1', 'nodeColor':'red'},
        {'id':'2', 'nodeColor':'white'},
        {'id':'3', 'nodeColor':'blue'}
    ],
    'edge':[
        {'id':'1', 'location':'north'},
        {'id':'1', 'location':'south'},
        {'id':'1', 'location':'east'}
    ]
}

使用默认parse()骨干将吞噬这个启动和数据的数组()分配的路径模型属性“节点”和“边缘”(不收藏。)因此,我们要确保我们的parse()与此交易适当。

parse: function(response) {

    // Check if response includes some nested collection data... our case 'nodes'
    if (_.has(response, 'nodes')){

         // Check if this model has a property called nodes
        if (!_.has(this, 'nodes')) {  // It does not...
            // So instantiate a collection and pass in raw data
            this.nodes = new NodeCollection(response.nodes);
        } else {
            // It does, so just reset the collection
            this.nodes.reset(response.nodes);
        }

        // Assuming the fetch gets this model id
        this.nodes.url = 'path/' + response.id + '/nodes';  // Set model relative URL

        // Delete the nodes so it doesn't clutter our model attributes
        delete response.nodes;
    }

    // Same for edge...

    return response;
}

您也可以使用自定义set()来处理您的子数据。 很多来回之间更好,操作后set()或做parse()我已经决定,我喜欢用parse()更多。 但我开放给其他人对这个想法。

利用set()来处理您的子数据

尽管parse()依赖于或者获取数据或将数据传递到一个集合的选项parse:true有人觉得优惠的改变set()函数。 同样,我不知道有一个正确的选择,但这里是如何将工作。

set: function(attributes, options) {
    // If we pass in nodes collection JSON array and this model has a nodes attribute
    // Assume we already set it as a collection
    if (_.has(attributes, 'nodes') && this.get("nodes")) {
        this.get('nodes').reset(attributes.nodes);
        delete attributes.nodes;
    } else if (_.has(attributes, 'nodes') && !this.get('nodes')) {
        this.set('nodes', new NodeCollection(attributes.nodes));
        delete attributes.nodes;
    }

    return Backbone.Model.prototype.set.call(this, attributes, options);
}

因此,如果我们已经有一个属性,它是一个集合,我们reset()它。 如果我们有一个属性,但它不是一个集合,我们实例化。 它你将它传递给原型之前,确保你的子数据的JSON阵列正确地翻译成收集是很重要的set() 骨干,不解释JSON数组作为一个集合,你只会得到一个直线上升的阵列。

因此,在果壳,你有关于如何去很多很多的选择。 再次,目前我赞成使用的混合initialize()当我知道的东西总会有那些子模型/收集和parse()时的情形只要求对可能的嵌套数据fetch()调用。

关于你的这个问题......(哦,是的,有一个问题)

您可以允许路径从哈希以各种方式实例子模型。 我只是给你4.您可以使用解析,如果你想,如果你知道你将要fetch()的路径模型或者甚至一个pathCollection ... pathCollection.fetch({parse:true})是否有一个惯例? 也许也许不是。 我喜欢用的,这取决于我想我会使用这些模型/收藏上下文的组合方式。

我要讨论一些这些做法非常开放,他们是好还是坏。 他们只是众多解决方案,我遇到的堆栈,并纳入自己的工作习惯,他们似乎工作对我蛮好。 :-)

让自己的咖啡和上背部轻拍,这是一个漫长的读取。



文章来源: Cast/initialize submodels of a Backbone Model