演员/初始化骨干模型子模型 [英] Cast/initialize submodels of a Backbone Model

查看:98
本文介绍了演员/初始化骨干模型子模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我觉得我有一个pretty简单的问题,这只是pretty难字,因此很难找到一个解决方案。设置:

I think I have a pretty simple problem that is just pretty difficult to word and therefore hard to find a solution for. Setup:


  • PathCollection是路径的Backbone.Collection

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

当我取PathCollection

When I fetch PathCollection

paths = new PathCollection()
paths.fetch()

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

obviously, Paths get instantiated. However, I'm missing the spot where I can allow a Path to instantiate its submodels from the attribute hashes. I can't really use parse, right? Basically im looking for the entry point for a model when its instantiated and set with attributes. I feel like there must be some convention for it.

推荐答案

所以,我写了一对夫妇使用解析()设置()来实例化和填充子模型和子集(嵌套数据)。但是,我还没有看到它整合了一些许多做法我已经看到了一个真正的COM prehensive答案。我倾向于逛了一下,当我写了很多,所以我可能离题一点点,但,这可能对人们通过类似的各种问题将是有益的。

So I've written a couple of answers regarding using parse() and set() to instantiate and populate sub-models and sub-collections (nested data). However, I haven't seen a really comprehensive answer that consolidates some of the many practices I've seen. I tend to ramble a bit when I write a lot so I might digress a little but this might be useful for people going through similar kinds of issues.

有几个方法可以做到这一点。使用解析()就是其中之一。操纵设置()是另一回事。在你的这些实例初始化()是另一个。这样做路径模型的所有外的又一(例如路径=新路径(); path.nodes =新NodeCollection(); 等)

There are a couple ways to do this. Using the parse() is one. Manipulating the set() is another. Instantiating these in your initialize() is another one. Doing it all outside of the Path model is another (e.g. path = new Path(); path.nodes = new NodeCollection(); etc.)

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

A second consideration is this. Do you want the nodes and edge collections to be model attributes? Or model properties?

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

Oh so many choices. A lot of freedom but sometimes (to our frustration) it makes it more difficult to determine the "right way."

由于这种经常出现,我要做一个长期职位和一个通过其中的一个。所以容忍我,因为我继续更新这个答案。

Since this comes up kind of often, I'm going to make a long post and go through these one by one. So bear with me as I continue to update this answer.

做这件事的车型外 - 简单而直接的

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

This is usually an easy way to add nested models and collections when you only need it on a particular model or collection.

path = new PathModel();

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

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

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

This is the simplest way and works well when you're dealing with one time models and collections that don't need to have a definition. Although you could easily produce these models in some method (e.g. view method) that constructs this object before doing anything with it.

初始化()分型/在每一个模型集合

Using initialize() Sub-model / collections in every model

如果你知道某个模型的每个实例将永远有一个子模型或子集,设置东西将是利用初始化()功能。

If you know that every instance of a certain model will always have a sub-model or sub-collection, the easiest way to set things up would be to utilize the initialize() function.

例如,把你的路径模型:

For example, take your Path model:

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。易peasy。

Now your sub-collections can be fetched like path.nodes.fetch() and it will route to the correct URL. Easy peasy.

解析()实例化和设置子数据

Using parse() for instantiating and setting sub-data

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

Perhaps, it gets a little more tricky if you don't want to assume every model is going to have a nodes and edge collections. Maybe you want nested models/collections only if the fetch() sends back such data. This is the case where using parse() can come in handy.

解析()的事情是,它采取任何JSON的服务器响应,并把它传递给模型才能够正确的命名空间和处理它集()功能。因此,我们可以检查是否包含一个模型或收集的原始数据,减少到父模型属性响应之前处理它。

The thing with parse() is that it takes ANY json server response and can properly namespace and deal with it before passing it to the model set() function. So, we can check to see if a model or collection raw data is included and deal with it before reducing the response down to parent model attributes.

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

For example, maybe from our server we get this response:

// 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'}
    ]
}

使用默认的解析()骨干会吞噬本和数据阵列()分配的路径模型属性节点和边缘(不收藏。)因此,我们要确保这​​个我们解析()交易恰如其分。

With the default parse() Backbone will gobble this up and assign your path model attributes 'nodes' and 'edge' with an array() of data (not collections.) So we want to make sure that our parse() deals with this appropriately.

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

您也可以使用自定义的设置()来处理你的子数据。很多来回之间哪个更好,操作后设置()解析这样做()我已经决定,我喜欢用解析()更多。但我开到其他人的这个想法。

You can also use a customized set() to deal with your sub-data. After much going back and forth between which is better, manipulating set() or doing it in parse() I've decided that I like to use parse() more. But I'm open to other people's thoughts on this.

设置()来处理你的子数据

Using set() to deal with your sub-data

解析()依赖于两种获取数据或将数据传递到一个集合的选项解析:真有些人觉得preferential更改设置()功能。同样,我不知道有一个正确的选择,但这里是如何将工作。

While parse() relies on either fetching the data or passing data into a collection with the option parse:true some people find it preferential to change the set() function. Again, I'm not sure there is a correct choice but here is how that would work.

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

所以,如果我们已经有一个属性,它是一个集合,我们复位()它。如果我们有一个属性,但它不是一个集合,我们实例化。以确保您将它传递给原型集之前子数据的JSON数组正确地翻译成集合是很重要的()。主干,不跨preT JSON数组作为收藏品,你会只得到一个直线上升的数组。

So if we already have an attribute and it is a collection, we reset() it. If we have an attribute but it isn't a collection, we instantiate it. It's important to make sure you correctly translate the JSON array of sub-data into a collection before you pass it to the prototype set(). Backbone, doesn't interpret the JSON array as a collection and you'll only get a straight-up array.

因此​​,在坚果壳,你有关于如何去很多很多的选择。再次,目前我倾向于使用初始化的混合(),当我知道事情总会有那些子模型/收藏和解析()时的情况只要求可能嵌套数据对取()来电。

So in a nut shell, you got many many options on how to go about. Again, currently I favor a mix of using initialize() when I know something will always have those sub-models/collections and parse() when the situation only calls for possible nested data on fetch() calls.

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

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

You can allow Path to instantiate sub-models from a hash in a variety of ways. I just gave you 4. You CAN use parse if you want, if you know you're going to be fetch() the path model OR maybe even a pathCollection... pathCollection.fetch({parse:true}) Is there a convention? Maybe maybe not. I like to use a combination of ways depending on the context in which I think I'll be using the models/collections.

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

I'm very open to discussion on some of these practices and whether they are good or bad. They are just many solutions I've come across on Stack and incorporated into my own working habits and they seem to work just fine for me. :-)

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

这篇关于演员/初始化骨干模型子模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆