Установка атрибутов в коллекции - магистраль js - PullRequest
55 голосов
/ 09 мая 2011

Коллекции в магистральной сети js не позволяют вам set атрибутов, но я часто обнаруживаю необходимость хранить метаинформацию о коллекции. Где лучше всего разместить эту информацию?

Ответы [ 4 ]

44 голосов
/ 09 мая 2011

Просто .extend коллекция с функцией хранения метаданных.

var MyCollection = Backbone.Collection.extend({
    initialize: function() {
        ...

        this._meta = {};
    },
    model: ...
    meta: function(prop, value) {
        if (value === undefined) {
            return this._meta[prop]
        } else {
            this._meta[prop] = value;
        }
    },
});

var collection = new MyCollection();
collection.add(someModels);
collection.meta("someProperty", value);

...

var value = collection.meta("someProperty");

Могут быть и более подходящие места для хранения определенных метаданных, но это полностью зависит от того, что такое метаданные.

Для хранения общих метаданных расширение вашего конструктора коллекции с помощью метода, который должен с этим справиться, должно работать.

Будьте осторожны, если эти метаданные нужно хранить и загружать с сервера, тогда у вас есть более сложная задача.

16 голосов
/ 19 сентября 2014

Вероятно, лучше использовать коллекцию именно так, как она была задумана: как набор моделей.(Жюльен уже прокомментировал это на ОП, я хотел бы дать объяснение, почему я думаю, что он прав)

Допустим, вы думаете о Библиотеке (коллекции) Книги (модели), как в документации Backbone.Примеры.Имеет смысл, что у вас есть метаинформация о библиотеке, которую вы хотите сохранить, например, адрес, где находится эта книжная библиотека.

Хитрость заключается не в том, чтобы рассматривать ее как метаинформацию.У вас есть библиотека с множеством свойств, и одним из этих свойств является коллекция книг.

var Book = Backbone.Model.extend({ 
    title: "Moby Dick"
});

var Collection = Backbone.Collection.extend({
    model: Book
});

var Library = {
    address: '45th Street',
    collection: Collection
};

В этом примере я определил библиотеку как простой объект JavaScript.Очевидно, вы также можете сделать библиотеку моделью, чтобы в ней были все навороты и опоры.Моя точка зрения заключается в том, что вам нужно представить реальность более реалистичным способом, сделав один шаг назад и увидев, что дополнительные свойства, которые вы хотите назначить для Коллекции, на самом деле являются родственными свойствами объекта на один уровень выше: в данном случае это Библиотека.


7 голосов
/ 12 мая 2012

Я обновил подход Raynos с помощью запуска событий, чтобы мы могли связываться с обновлением атрибутов коллекции.

cls.groups = Backbone.Collection.extend({

    // ...

    // Reference to this collection's model.
    model: cls.group,

    initialize: function() {
        this._attributes = {}
    },

    // Extend collection with ability to store attributes and trigger events on attributes changing
    attr: function(prop, value) {
        if (value === undefined) {
            return this._attributes[prop]
        } else {
            this._attributes[prop] = value;
            this.trigger('change:' + prop, value);
        }
    },

    // ...

});


cls.group = Backbone.View.extend({

    // ...

    initialize: function() {

        // Catching attribute update
        app.groups.on('change:selected', function(value) {
            // ...
        }, this);
    },

    // ...

    events: {
        'click' : function(e) {
            // Set collection meta attribute on model's view click event
            app.groups.attr('selected', this.model.cid);
        }
    }

    // ...

});
3 голосов
/ 30 мая 2011

Использование функции meta решения @Raynos только с одним параметром у меня не работает. Поэтому я использовал следующий код:

var MyCollection = Backbone.Collection.extend({
    initialize: function() {
        this._meta = {};
    },
    put: function(prop, value) {
        this._meta[prop] = value;
    },
    get: function(prop) {
        return this._meta[prop];
    }
});

var collection = new MyCollection();
collection.put("someProperty", 12);
alert(collection.get("someProperty"));

Надеюсь, это поможет.

...