Knockout.js model inheritance
DRY. If you are copy pasting your model methods/properties etc - you are on wrong way. Just inherit them from base model. Here is example:
<!DOCTYPE html>
<html>
<head>
<title>inheritance simple</title>
<meta charset="utf-8" />
</head>
<body>
<div class="container">
<div data-bind="foreach: items">
<p data-bind="text: toString()"></p>
</div>
</div>
<script type="text/javascript" src="components/jquery/jquery.js"></script>
<script type="text/javascript" src="components/knockout/build/output/knockout-latest.debug.js"></script>
<script type="text/javascript">
// Base model, that will be inherited
// notice that options are provided as object, rather than simple arguments
function QuestionBaseModel(options) {
this.id = ko.observable()
this.name = ko.observable()
this.importance = ko.observable()
this.importanceOptions = ['Non important', 'Semi important', 'Important']
this.answer = ko.observable()
// found at: http://stackoverflow.com/questions/10520400/knockout-issue-with-prototypical-inheritance
this.init = function (options) {
if (options) {
for (key in options) {
if (typeof this[key] === 'function') {
this[key](options[key])
} else {
this[key] = options[key]
}
}
//if(options.id) this.id(options.id);
//if(options.name) this.name(options.name);
//if(options.importance) this.importance(options.importance);
//if(options.answer) this.answer(options.answer);
}
}
this.init.apply(this, arguments) // apply given options
}
function QuestionExperienceModel(options) {
this.answerOptions = ['little', '2+ years', 'huge'] // provide available answers
this.toString = function () {
return ko.toJSON(this)
}
this.init.apply(this, arguments) // apply given options
}
QuestionExperienceModel.prototype = new QuestionBaseModel() // inherit from base model
function QuestionLanguageModel(options) {
this.language = ko.observable(options.language) // additional field
this.languageOptions = ['English', 'Ukrainian'] // and its options
this.answerOptions = ['little', 'good', 'carrier'] // provide available answers
// override name, so it is no longer writable
this.name = ko.computed(function () {
return 'Your knowledge of ' + this.language()
}, this)
this.toString = function () {
return ko.toJSON(this)
}
this.init.apply(this, arguments) // apply given options
}
QuestionLanguageModel.prototype = new QuestionBaseModel() // inherit from base model
function List() {
var self = this
self.items = ko.observableArray([
new QuestionExperienceModel({ id: 1, name: 'Your experience in JS', importance: 'Important', answer: '2+ years' }),
new QuestionLanguageModel({ id: 2, importance: 'Semi important', answer: 'good', language: 'Ukrainian' })
])
}
ko.applyBindings(new List())
</script>
</body>
</html>