2013-11-21 125 views
1

我使用module pattern打造一個模式,這是接近完成一個小測驗。有一個在上面寫着「重試」,將重新啓動測驗測驗的最後一個按鈕,我有一個堅硬的時間思考的乾燥方式來設置屬性(應用程序瓦爾列表)重置其默認值。返回的JavaScript(jQuery的)對象屬性爲默認狀態

這是我現在所擁有的:

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可以使用。此外,我不明白如何/在哪裏存儲數據以及如何將數據映射回來,因爲我不完全理解這是什麼類型的數據(是「設置」對象屬性,而且它是值子屬性?或者它是一個多維數組?什麼我在存儲數據後檢索其默認值?等),所以任何一種深入的解釋或鏈接到的數據類型我們的信息在這裏工作是一個額外的好處!

+1

爲什麼不保持默認設置爲私有變量,然後分配對象設置的克隆需要的時候? – Shreyas

+0

什麼在世界上?有人編輯我的代碼並大規模屠殺它。現在修復,請再看一遍。 –

+0

@Shreyas - 這聽起來像一個偉大的路要走。你介意給我一個代碼示例嗎? –

回答

3

創建QuizApp稱爲默認的變量外,並指定默認值給它。

然後,當你聲明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

肖恩,我認爲這就是我要找的。我意識到我遺漏了init代碼,所以「s」var不清楚它的目的是什麼。我更新了我的問題,所以現在更清楚了 - 你會介意更新匹配的答案(如果有必要?)我現在正在測試,如果它能正常工作,我會接受 –

+1

+1:使用jQuery這是最好的解決方案。 –

+0

@IvanDurst我更新了我的代碼,以配合您的問題代碼,我提出了一個建議,以保護您的代碼與任何外部的代碼 –

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 

我沒有太多使用字符串標識符的粉絲的,但大多數人似乎並不介意做。

+0

我很感激你花時間寫出來。矯枉過正的我的情況一點點......如果我不能得到其他的答案中的一個工作,我會採取有關默認值的建議。 –

+0

沒問題。查看我添加的第二個解決方案。 –

+0

我應該補充說我的是香草JS。既然你使用jQuery(顯然),'extend'方法可能是最好的。這有點類似於我的第二個解決方案,雖然不完全相同(我不復制該對象)。 –

2

不要設置settingsdefaults。而是複製它們。

// 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對象。

+0

+1:提起與分配'S =默認衝突;'直接 –