将Backbone的模型重置为初始默认值的最简单方法是什么?

时间:2011-07-31 12:24:56

标签: javascript backbone.js backbone-model

我的模型已经有defaults哈希。当视图/页面的某些部分被重置时,我希望将模型重置为其原始默认值。

目前,我明确将每个属性设置为其默认值。是否内置了任何内容或JavaScript / Underscore.js / Backbone.js / jQuery函数,我可以用它来在一个语句中执行此操作?

7 个答案:

答案 0 :(得分:120)

myModel.clear().set(myModel.defaults);

答案 1 :(得分:5)

当模型具有非空的初始对象属性时,我会这样做。

首先,将默认值定义为函数

var MyModel = Backbone.Model.extends({

    defaults:function(){

        return {
            AnArrayTypeProp:[]
        };
    }

});

第二,需要时将模型重置为默认值

model.clear().set(model.defaults());

答案 2 :(得分:5)

我想出了以下方法:

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

{silent: true}调用中使用clear()可确保不会触发change事件;它只会在set()来电时触发。

答案 3 :(得分:4)

根据saabeilin的答案和Backbone's annotated source,我找到了一个最佳功能,以满足重置模型的需要。

可重复使用的重置

/**
 * 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本身:

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

免责声明:如果您正在编写JavaScript lib或Backbone插件,请不要这样做,因为它可能会与另一个lib冲突,或者它可能导致与使用者所期望的行为不同的行为你的代码。

答案 4 :(得分:3)

我还考虑过将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事件。

答案 5 :(得分:1)

如何用新的空模型覆盖当前模型的值:

myModel = new model(); // default values will be considered

答案 6 :(得分:0)

我的解决方法是:

from PyQt5 import QtCore, QtGui, QtWidgets
import sys, os, configparser

config = configparser.ConfigParser()
config.read("Settings.ini")

# Config get setting and change setting
#print(config.get("Main", "language"))
#config.set("Main", "language", "danish")
#with open("Settings.ini", "w") as cfg_file:
    #config.write(cfg_file)

class App(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        # Window Settings
        self.x, self.y, self.w, self.h = 0, 0, 300, 200
        self.setGeometry(self.x, self.y, self.w, self.h)

        self.window = MainWindow(self)
        self.setCentralWidget(self.window)
        self.setWindowTitle("Window title") # Window Title
        self.show()

class GeneralWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(GeneralWidget, self).__init__(parent)
        lay = QtWidgets.QVBoxLayout(self)
        # Buttons
        button_start = QtWidgets.QPushButton("start") #self.lang["btn_start"])
        button_stop = QtWidgets.QPushButton("stop") #self.lang["btn_stop"])

        # Button Extra
        button_start.setToolTip("This is a tooltip for the button!")    # Message to show when mouse hover
        button_start.clicked.connect(self.on_click)

        button_stop.clicked.connect(self.on_click)

        lay.addWidget(button_start)
        lay.addWidget(button_stop)
        lay.addStretch()

    @QtCore.pyqtSlot()
    def on_click(self):
        button = self.sender().text()
        if button == self.lang["btn_start"]:
            print("Dank")
        elif button == self.lang["btn_stop"]:
            print("Not dank")


class OptionsWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(OptionsWidget, self).__init__(parent)
        lay = QtWidgets.QVBoxLayout(self)
        hlay = QtWidgets.QHBoxLayout()
        lay.addLayout(hlay)
        lay.addStretch()

        label_language = QtWidgets.QLabel("Language")
        combo_language = QtWidgets.QComboBox(self)
        combo_language.addItem("item1") #self.lang["language_danish"])
        combo_language.addItem("item2") #self.lang["language_english"])
        hlay.addWidget(label_language)
        hlay.addWidget(combo_language)



class MainWindow(QtWidgets.QWidget):        
    def __init__(self, parent):   
        super(MainWindow, self).__init__(parent)
        layout = QtWidgets.QVBoxLayout(self)
        # Run this after settings
        # self.lang = getLang(config.get("Main", "language"))
        # Initialize tabs
        tab_holder = QtWidgets.QTabWidget()   # Create tab holder
        tab_1 = GeneralWidget()           # Tab one
        tab_2 = OptionsWidget()           # Tab two
        # Add tabs
        tab_holder.addTab(tab_1, "General") #self.lang["tab_1_title"]) # Add "tab1" to the tabs holder "tabs"
        tab_holder.addTab(tab_2, "Options") #self.lang["tab_2_title"]) # Add "tab2" to the tabs holder "tabs" 

        layout.addWidget(tab_holder)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())