Persisting & loading metadata in a backbone.js col

2019-01-21 23:47发布

I have a situation using backbone.js where I have a collection of models, and some additional information about the models. For example, imagine that I'm returning a list of amounts: they have a quantity associated with each model. Assume now that the unit for each of the amounts is always the same: say quarts. Then the json object I get back from my service might be something like:

{
    dataPoints: [
         {quantity: 5 },
         {quantity: 10 },
         ...
    ],
    unit : quarts
 }

Now backbone collections have no real mechanism for natively associating this meta-data with the collection, but it was suggested to me in this question: Setting attributes on a collection - backbone js that I can extend the collection with a .meta(property, [value]) style function - which is a great solution. However, naturally it follows that we'd like to be able to cleanly retrieve this data from a json response like the one we have above.

Backbone.js gives us the parse(response) function, which allows us to specify where to extract the collection's list of models from in combination with the url attribute. There is no way that I'm aware of, however, to make a more intelligent function without overloading fetch() which would remove the partial functionality that is already available.

My question is this: is there a better option than overloading fetch() (and trying it to call it's superclass implementation) to achieve what I want to achieve?

Thanks

2条回答
戒情不戒烟
2楼-- · 2019-01-22 00:27

This meta data does not belong on the collection. It belongs in the name or some other descriptor of the code. Your code should declaratively know that the collection it has is only full of quartz elements. It already does since the url points to quartz elements.

var quartzCollection = new FooCollection();
quartzCollection.url = quartzurl;
quartzCollection.fetch();

If you really need to get this data why don't you just call

_.uniq(quartzCollecion.pluck("unit"))[0];

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-01-22 00:32

Personally, I would wrap the Collection inside another Model, and then override parse, like so:

var DataPointsCollection = Backbone.Collection.extend({ /* etc etc */ });
var CollectionContainer = Backbone.Model.extend({
    defaults: {
        dataPoints: new DataPointsCollection(),
        unit: "quarts"
    },
    parse: function(obj) {
        // update the inner collection
        this.get("dataPoints").refresh(obj.dataPoints);

        // this mightn't be necessary
        delete obj.dataPoints;

        return obj;
    }
});

The Collection.refresh() call updates the model with new values. Passing in a custom meta value to the Collection as previously suggested might stop you from being able to bind to those meta values.

查看更多
登录 后发表回答