在其他框架的其他MVVM API中,例如Caliburn Micro for WPF,您可以使用子类视图模型。作为一个例子,我有这个视图模型
Customer
Id : int
Selected : bool
Name : string
Edit : ViewModel
根据不同的客户类型,我将有不同的Edit ViewModel,在Caliburn micro中,它会自动呈现正确的视图,具体取决于ViewMOdel的类型,类型是JS中不存在的类型,但是你能否在某种程度上实现这一点敲除?
答案 0 :(得分:1)
感谢Mike,你的解决方案并不是我所需要的,我做了类似的服务器端,但我们的json对象是从CQRS读取模型库中读取的。
事实证明,命名模板就是我所追求的.Heres是一个小小的小提琴,显示我做了什么(在我们的实际场景中,子模型的属性将在实际的客户对象上)
<强>更新强> 刚刚看到这个答案得到了提升。有更优雅的方法,例如使用我在这里找到的配置库上的约定
https://github.com/AndersMalmgren/Knockout.BindingConventions
它有一个使用该类型的模板的约定,所以使用你喜欢的OO模式
http://ejohn.org/blog/simple-javascript-inheritance/
定义不同的类型,重要的是它们后缀为模型或 ViewModel
模板应具有相同的名称,但后缀为查看
<script type="text/html" id="MyView">
<input data-name="myValue" />
</script>
答案 1 :(得分:0)
我做了类似于我想你想做的事情。
我所做的是在服务器上创建视图模型,将它们序列化为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);
});
嗯。结果证明是一些代码。这就是我如何弥合服务器和客户端之间的差距,同时仍然能够根据类型名称和类似的东西选择模型。它还允许我在服务器上定义数据结构,同时在挖空视图模型中定义表示特定的行为。映射插件有点神奇,但一个缺点是你没有在knockout视图模型中看到数据结构,但我已经接受了。另外,请注意名称的外壳不同,如果你不能忍受,Newtonsofts Json序列化器在序列化时可以更换外壳。我选择不这样做,因为它帮助我看到服务器的内容以及我在视图模型中定义的内容。