Reputation: 93
Question: Is it possible to have different views for a model based on the value it has for a field?
Explanation: I have a model with a Settings and Type field in it. The settings can be different settings model based on the type. I would like to switch out the view for the settings based on the value of Type.
I have minor experience with knockout, and would like this to scalable for many different types.
I tried using a ko.computedObservable with a switch statement to return a function() that defines the settings in it; such as:
self.Settings = ko.computed(function () {
switch (self.Type()) {
case "Type1":
return new Type1(model.Settings);
case "Type2":
return new Type2(model.Settings);
}
});
Type1 and Type2 are functions with the unique settings for each type of the model. This failed miserably.
I may just be over complicating the problem, so a second pair of eyes and any suggestions would be fantastic!
Thank you in advance!
Upvotes: 1
Views: 66
Reputation: 32202
Consider using templates for your different views. By doing so, you can then make use of the ability to dynamically choose which template is rendered based on a property of your viewmodel. For example, assuming your viewmodel looks something like:
var vm = function() {
var self = this;
self.Settings = ko.computed(function () {
switch (self.Type()) {
case "Type1":
return new Type1(model.Settings);
case "Type2":
return new Type2(model.Settings);
}
});
//Based on your example computed, we'll return a different template name
//for each object type you're returning
self.templateName = function(t) {
if (t instanceof Type1)
return "template_type1";
if (t instanceof Type2)
return "template_type2";
return "template_unknown";
}
};
Your main view then binds to your collection as normal, but with the template
binding making use of the function defined on your viewmodel:
<div data-bind="template: { name: templateName, foreach: Settings }"></div>
You can then include templates in your script that bind to specific properties of each type:
<script id="template_type1" type="text/html">
<span data-bind="text: name"></span>
</script>
<script id="template_type2" type="text/html">
<h3 data-bind="text: title"></h3>
</script>
<script id="template_unknown" type="text/html">
<span>Unknown item type</span>
</script>
Upvotes: 2