Подтвердить что ты не робот

Установка атрибутов в коллекции - магистраль js

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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


Ответ 2

Просто .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");

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

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

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

Ответ 3

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

cls.groups = Backbone.Collection.extend({

    // ...

    // Reference to this collection 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 view click event
            app.groups.attr('selected', this.model.cid);
        }
    }

    // ...

});

Ответ 4

Использование функции 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"));

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