I have done something similar to what I think you want to do.
What I do is to create view models on the server, serialize them into json and use the mapping plugin to create Knockout viewmodels.
I have a common base class in C# and implementation classes that have various data structures. Then I only define behaviour in knockout.
Something like this:
public abstract MyBase : IDefineMyBase {
public string Type { get { return this.GetType().Name; } }
}
public class MyFirstEditModel : MyBase {
public string Something { get; set; }
}
I use ASP.NET MVC to serve this to knockout:
public ActionResult MyAction() {
var model = {
EditModels = new IDefineMyBase[] {
new MyFirstEditModel {
Something = "Some thing"
},
... other implementations
}
};
// AsJson is a serialization extension method
return View("MyView", (object)model.AsJson());
}
In Knockout, I use it like this:
// This is a behaviour base "template" that will be applied for all editmodels
var editModel = function(data) {
// Map the edit model specific data to *this*
ko.mapping.fromJS(data, {}, this);
// Apply implementation specific behaviour to this instance of the model
eval(this.Type() + '(this)'); // example: MyFirstEditModel(this);
}
// This is specific behaviour for MyFirstEditModel
var MyFirstEditModel = function(base) {
base.someBindableSpecificFunction = function() {
// You can use data from the implementation here.
alert(base.Something());
};
}
// This is the base view model where you can have all the main functionality
var viewModel = function(base) {
ko.utils.arrayForEach(data.EditModels(), function (editModel) {
s.Parent = base;
// example: base.MyFirstEditModel = editModel;
eval('base.' + s.Type() + ' = editModel');
});
}
// This is mapping instructions
var mapping = {
'EditModels': {
create: function (options) {
return new editModel(options.data);
}
}
};
$(document).ready(function () {
// Map the server side model to knockout
var mapped = ko.mapping.fromJS(@Html.Raw(Model), mapping, vm);
// Add behaviour to the mapped data
viewModel(mapped);
ko.applyBindings(vm);
});
Hmm. That turned out to be a bit of code. This is how I bridge the gap between the server and the client while still being able to choose models based on Type name and things like that. It also lets me define data structures on the server while defining presentation specific behaviour in knockout view models. The mapping plugin is a bit magical but one drawback is that you don't see the data structure in the knockout viewmodels, but I have accepted that. And also, note that the casing of names differ and if you can't stand that the Newtonsofts Json serializer can change casing when serializing. I have chosen not to do so since it helps me see what is from the server and what I have defined in the view models.