Самый простой способ сбросить модель Backbone к начальным значениям по умолчанию? - PullRequest
59 голосов
/ 31 июля 2011

У моих моделей уже есть хэш defaults. Когда части представления / страницы сбрасываются, я хочу вернуть модели к исходным значениям по умолчанию.

В настоящее время я явно устанавливаю для каждого атрибута значение по умолчанию. Есть ли что-нибудь встроенное или функция JavaScript / Underscore.js / Backbone.js / jQuery, которую я мог бы использовать, чтобы сделать это в одном выражении?

Ответы [ 7 ]

120 голосов
/ 31 июля 2011
myModel.clear().set(myModel.defaults);
5 голосов
/ 14 апреля 2016

Я придумал следующий подход:

reset: function () {
    this.clear({silent: true});
    this.set(this.defaults);
}

Наличие {silent: true} в вызове clear() гарантирует, что событие change не будет запущено; это будет огонь только на set() вызов.

5 голосов
/ 20 июля 2014

Я делаю это, когда модель имеет ненулевые начальные свойства объекта.

сначала определите значения по умолчанию как функцию

var MyModel = Backbone.Model.extends({

    defaults:function(){

        return {
            AnArrayTypeProp:[]
        };
    }

});

секунду, когда это необходимо длясбросить модель по умолчанию

model.clear().set(model.defaults());
4 голосов
/ 18 апреля 2016

Основываясь на ответе saabeilin и источника, аннотированного Backbone , я получил оптимальную функцию для удовлетворения потребности в сбросе модели.

Повторный сброс

/**
 * Clears the model's attributes and sets the default attributes.
 * @param  {Object} attrs to overwrite defaults
 * @param  {Object} options  to pass with the "set" call.
 * @return {Backbone.Model}  this object, to chain function calls.
 */
reset: function(attrs, options) {
    // adds default option reset to true
    options = _.extend({ reset: true }, options);

    // ensure default params
    var defaults = _.result(this, 'defaults');
    attrs = _.defaults(_.extend({}, defaults, attrs), defaults);

    // apply
    this.clear({ silent: true }).set(attrs, options);

    // triggers a custom event, namespaced to model in order
    // to avoid collision with collection's native reset event
    // when listening to a collection.
    if (!options.silent) this.trigger('model:reset', this, options);

    return this;
},

Следующая строка гарантирует, что даже если атрибут передан как неопределенный { test: undefined }, он все равно будет иметь значение по умолчанию.

attrs = _.defaults(_.extend({}, defaults, attrs), defaults);

Вот пример:

var defaults = { test: 1 }, 
    attrs = { test: undefined };

_.extend({}, defaults, attrs);                       // {test: undefined}
_.defaults(_.extend({}, defaults, attrs), defaults); // {test: 1}

Расширение Backbone

И если вы хотите его для всех моделей Backbone, вы можете расширить саму Backbone:

_.extend(Backbone.Model.prototype, {
    reset: function(attributes, options){
        /* ... */
    }
});

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

3 голосов
/ 12 октября 2014

Я также думал об использовании model.clear() и model.set() в сочетании.Затем я столкнулся с проблемой, что теперь я запускаю событие change дважды.Использование опции silent при вызове model.clear() не вариант, потому что я также хочу, чтобы событие change срабатывало, когда свойство не было установлено.

В итоге я добавил model.reset()метод.Он принимает новый хэш атрибутов и заполняет этот хэш undefined значениями для старых ключей атрибутов, которых нет в новом хеш-атрибуте.

Model.prototype.reset = function(attrs, options) {
    for (var key in this.attributes) {
        if (key in attrs) continue;
        attrs[key] = void 0;
    }

    return this.set(attrs, options);
};

Таким образом вы сбрасываете старые атрибуты моделей и получаете действительные change событие для каждого старого и нового атрибута.

1 голос
/ 11 мая 2015

Как насчет переопределения значения текущей модели новой пустой моделью:

myModel = new model(); // default values will be considered
0 голосов
/ 24 августа 2018

Мои решения:

model.clear({silent: true}).set(model.defaults);
...