我正在使用module pattern在模态中构建一个小测验,这几乎已经完成了。测验结束时有一个按钮,说“重试”会重新开始测验,而我很难想到一种干燥的方法来重置设置属性(应用程序的变量列表)到它的默认值。
这就是我现在所拥有的:
jQuery(function($) {
var s,
QuizApp = {
settings: {
timer: null,
isPaused: false,
count: null,
correctAnswer: null,
score: 0,
questionCounter: 1
},
init: function() {
s = this.settings;
this.questionsGet();
this.bindUIActions();
},
// Code omitted for event handlers and such
resetQuiz: function() {
s.timer = null;
s.isPaused = false;
s.count = null;
s.correctAnswer = null;
s.score = 0;
s.questionCounter = 1;
},
},
}; $(function() {
QuizApp.init();
});
});
不是很干 - 实际上非常糟糕。我想要的是:
jQuery(function ($) {
var s,
QuizApp = {
settings: {
timer: null,
isPaused: false,
count: null,
correctAnswer: null,
score: 0,
questionCounter: 1,
defaults: { /* pseudo code to store settings here */ }
},
resetQuiz: function () {
s = s.defaults // pseudo code to reset the settings to the value stored in defaults
},
};
$(function () {
QuizApp.init();
});
});
或者更好的东西,如果你能想到的话。我已经完成了大量搜索“重置对象属性”和“克隆对象属性”,但我找不到任何解释如何执行此操作的内容。显然,jQuery可以使用。
此外,我不明白如何/在何处存储数据以及如何将数据映射回来因为我不完全了解这是什么类型的数据(“设置”是对象属性,它的值是子属性?或者它是一个多维数组?我将数据存储在以后检索其默认值等等),所以任何类型的深入解释或链接到我们正在工作的数据类型的信息这里有额外的奖励!
答案 0 :(得分:3)
在QuizApp之外创建一个名为defaults的变量,并为其指定默认值。
然后,当您声明QuizApp settings: $.extend({},defaults)
然后在restartQuiz()
函数内声明s = $.extend({},defaults);
我还建议用
包装你的代码; (function($){
"strict mode";
})();
这可以防止与覆盖外部变量发生冲突
; (function(){
"strict mode";
jQuery(function($) {
var s,
defaults = {
timer: null,
isPaused: false,
count: null,
correctAnswer: null,
score: 0,
questionCounter: 1
},
QuizApp = {
settings: $.extend({},defaults),
init: function() {
s = $.extend({},defaults);
this.questionsGet();
this.bindUIActions();
},
resetQuiz: function() {
s = $.extend({},defaults); // pseudo code to reset the settings to the value stored in defaults
},
};
$(function() {
QuizApp.init();
});
})(jQuery);
答案 1 :(得分:2)
请勿将settings
设置为 defaults
。而是复制它们。
// set up the defaults somewhere in your module
var defaults = {/* stuff */};
// then when initing and resetting, use `$.extend` or your clone flavor
// of choice to assign `s` a new copy of the defaults
s = $.extend({}, defaults);
这种s.foo = "bar"
实际上并不会更改defaults
对象。
答案 2 :(得分:1)
如果您真的不想使用默认值保留对象的第二个副本,我认为您正在寻找类似的东西:
function PropertyHolder (defaultValue) {
this.defaultValue = defaultValue;
this.currentValue = defaultValue;
}
PropertyHolder.prototype.reset = function () {
this.currentValue = this.defaultValue;
};
PropertyHolder.prototype.setValue = function (newValue) {
this.currentValue = newValue;
};
PropertyHolder.prototype.getValue = function () {
return this.currentValue;
};
function Settings (settings) {
for( var key in settings ) {
this[key] = new PropertyHolder( settings[key] );
}
};
Settings.prototype.reset = function () {
for( var key in this ) {
if( this[key] instanceof PropertyHolder ) {
this[key].reset();
}
}
};
var settings = new Settings( {
valueA: 42,
valueB: ["Hello", "World"]
} );
console.log( settings.valueA.getValue() ); // 42
settings.valueA.setValue( -1 );
console.log( settings.valueA.getValue() ); // -1
settings.reset();
console.log( settings.valueA.getValue() ); // 42
大多数情况下,这可以大大改进。这只是为了实现这个想法。但是,对于一个小的简单设置对象,我认为只使用默认值保留第二个副本没有任何问题。它可能有点重复,但在这种情况下并不是那么糟糕。
但是,这也可能对您有所帮助以避免重复:
var defaults = {
'valueA': 42,
'valueB': ["Hello", "World"]
};
var settings = {};
var getSetting = function (setting) {
return typeof settings[setting] !== 'undefined' ? settings[setting] : defaults[setting];
};
var resetSettings = function () {
settings = {};
};
console.log( getSetting( 'valueA' ) ); // 42
settings['valueA'] = -1;
console.log( getSetting( 'valueA' ) ); // -1
resetSettings();
console.log( getSetting( 'valueA' ) ); // 42
我不太喜欢使用字符串标识符,但大多数人似乎并不介意。