我做了一些类似于我认为你想做的事情。
我所做的是在服务器上创建视图模型,将它们序列化为 json 并使用映射插件创建 Knockout 视图模型。
我有一个 C# 中的通用基类和具有各种数据结构的实现类。然后我只定义淘汰赛中的行为。
类似这样的:
public abstract MyBase : IDefineMyBase {
public string Type { get { return this.GetType().Name; } }
}
public class MyFirstEditModel : MyBase {
public string Something { get; set; }
}
我使用 ASP.NET MVC 来服务这个淘汰赛:
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());
}
在 Knockout 中,我是这样使用它的:
// 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);
});
嗯。原来是一段代码。这就是我如何在服务器和客户端之间架起桥梁,同时仍然能够根据类型名称等选择模型。它还允许我在服务器上定义数据结构,同时在剔除视图模型中定义表示特定的行为。映射插件有点神奇,但一个缺点是您在淘汰视图模型中看不到数据结构,但我接受了这一点。此外,请注意名称的大小写不同,如果您不能忍受 Newtonsofts Json 序列化程序在序列化时可以更改大小写。我选择不这样做,因为它可以帮助我查看来自服务器的内容以及我在视图模型中定义的内容。