问题 如何在ASP.NET MVC项目中为knockout生成客户端视图模型?


我目前正在研究ASP.NET MVC解决方案,最近又推出了Knockout(MVVM JS库)和Wijmo(一组jQuery UI小部件)。

随着Knockout的引入,我还需要在客户端有模型,所以为此我将序列化C#ViewModel并将其附加到视图使用 data-model="@Model.ToJson()"。这允许我从JS检索模型并对一切应用一些客户端的爱。

但是,knockout需要一切都是可观察的,所以我需要声明一个单独的客户端ViewModel并映射数据模型对象的所有内容。这感觉非常像重复的努力,我想以某种方式避免它。

我希望有人有一个共享的工具或技术,这将允许我直接从服务器渲染淘汰ViewModel。可能的解决方案包括:

  • 自定义JSON序列化,以将可观察视图模型直接呈现给data-model属性中的输出。
  • 自动客户端转换(我听说过ko-autobind,但我不确定它是否是推荐的路径或者它是如何稳定/完成的)
  • 我没有想到的东西

我希望解决方案是通用的和自动的,因为我目前用手工输入可观察的客户端视图模型的方法实在是太没用了。

你是如何解决这个问题的?


10601
2018-06-02 22:04


起源



答案:


根据他们的教程,它只是一个简单的 .map 功能

如果这是ViewModel

function Task(data) {
    this.title = ko.observable(data.title);
    this.isDone = ko.observable(data.isDone);
}

而这个函数从服务器获取数据,它使用 .map 用于将服务器数据直接注入VM的功能

// Data
var self = this;
self.tasks = ko.observableArray([]);

// Load initial state from server, convert it to Task instances, then populate self.tasks
$.getJSON("/tasks", function(allData) {
    var mappedTasks = $.map(allData, function(item) {
        return new Task(item)
    });
    self.tasks(mappedTasks);
});

对于ko映射 http://knockoutjs.com/documentation/plugins-mapping.html

对于自动绑定,这是一个例子

https://groups.google.com/forum/#!msg/knockoutjs/IJTx37UXQVw/UTrWdEK1C-oJ


10
2018-06-02 22:11



这就是我现在正在做的事情,因为你需要为每个视图模型提供一个Task函数。我正在寻找的解决方案不应该要求我为每个视图模型都有一个方法或类,而是需要一个共享的代码片段来进行转换(客户端或服务器端)。如果我弄错了,请纠正我。 - Morten Mertner
那就是你想要autobind我认为它被调用的地方,或者是,否则你需要每个都有一个:-( - CD Smith
autobind有效吗?它是7个月前的最后一次更新,自述文件说“这是初始提交,只支持绑定元素名称到viewmodel”,这似乎意味着缺少某些东西,或者某些情况不会有效,而不是非常明确。此外,作者在另一篇文章中链接的jsfiddle被破坏了,所以如果这是你的建议可以使用一个例子;) - Morten Mertner
这是网站上的一些信息 knockoutjs.com/documentation/plugins-mapping.html这里是Git回购,一个月前的版本2.1.2显示作者:史蒂夫S. github.com/SteveSanderson/knockout.mapping/tree/master/build/... - CD Smith
看起来ko-mapping是更好的选择 - CD Smith


答案:


根据他们的教程,它只是一个简单的 .map 功能

如果这是ViewModel

function Task(data) {
    this.title = ko.observable(data.title);
    this.isDone = ko.observable(data.isDone);
}

而这个函数从服务器获取数据,它使用 .map 用于将服务器数据直接注入VM的功能

// Data
var self = this;
self.tasks = ko.observableArray([]);

// Load initial state from server, convert it to Task instances, then populate self.tasks
$.getJSON("/tasks", function(allData) {
    var mappedTasks = $.map(allData, function(item) {
        return new Task(item)
    });
    self.tasks(mappedTasks);
});

对于ko映射 http://knockoutjs.com/documentation/plugins-mapping.html

对于自动绑定,这是一个例子

https://groups.google.com/forum/#!msg/knockoutjs/IJTx37UXQVw/UTrWdEK1C-oJ


10
2018-06-02 22:11



这就是我现在正在做的事情,因为你需要为每个视图模型提供一个Task函数。我正在寻找的解决方案不应该要求我为每个视图模型都有一个方法或类,而是需要一个共享的代码片段来进行转换(客户端或服务器端)。如果我弄错了,请纠正我。 - Morten Mertner
那就是你想要autobind我认为它被调用的地方,或者是,否则你需要每个都有一个:-( - CD Smith
autobind有效吗?它是7个月前的最后一次更新,自述文件说“这是初始提交,只支持绑定元素名称到viewmodel”,这似乎意味着缺少某些东西,或者某些情况不会有效,而不是非常明确。此外,作者在另一篇文章中链接的jsfiddle被破坏了,所以如果这是你的建议可以使用一个例子;) - Morten Mertner
这是网站上的一些信息 knockoutjs.com/documentation/plugins-mapping.html这里是Git回购,一个月前的版本2.1.2显示作者:史蒂夫S. github.com/SteveSanderson/knockout.mapping/tree/master/build/... - CD Smith
看起来ko-mapping是更好的选择 - CD Smith


试试这个visual studio的插件 http://visualstudiogallery.msdn.microsoft.com/32c15a80-1c54-4e96-a83f-7cd57573a5d2


6
2017-10-24 12:27



这看起来很有用,谢谢! :-) - Tom Chantler