ASP.NET MVC结合Knockout和Web API:是否有意义?

18

在使用ASP.NET MVC3或4时,是否有意义使用KnockoutJS的ViewModels?因为这样做并不够DRY,对吗?我需要为EF编写模型,为MVC视图编写Viewmodels,并且为Knockout编写Viewmodels… 这样做会失去很多魔力。例如,自动客户端验证。

如果坚持使用MVVM模式,是否有必要使用MVC?


通过使用 Knockout,您正在交换一种“魔法”来实现另一种(例如自动更新 UI 属性等)。 - Steve Greatrex
Steve,是的,我知道并且喜欢Knockout的“魔力”。对于一个有很多表单和验证的中型Web应用程序,你会选择哪种方式? - Matze-Berlin
3
为什么不混合使用 - 使用MVC生成表单,使用不显眼验证来处理客户端验证,需要更多交互式客户端时再使用Knockout? - Steve Greatrex
1
我使用 knockout 的大多数项目都规模较小。 - Steve Greatrex
1
这个链接里有一个解决方案:https://dev59.com/Om025IYBdhLWcg3w4qEx#6559734 - user1347229
5个回答

15

通过Knockout Mapping,你可以自动从你的MVC模型生成一个KO视图模型。

这是一种合适的模式:你的模型是原始实体,即数据。你的视图是用户界面。而你的视图模型则是适应特定视图的模型。


3
这个方法很合理,这也是我使用的方法。MVC4附带了Knockout,我希望有一些使用Knockout绑定的模板(特别是与新的SPI内容一起使用)。 - Joel Cochran

7
这可能是一个不受欢迎的答案,但我不使用“ko.mapping”将我的C# POCOs翻译成JS视图模型。实际上有两个原因。
第一个原因是缺乏控制。如果允许,“ko.mapping”会将所有内容转换为observable。这可能会导致那些不需要observable的字段产生很多开销。
第二个原因与可扩展性有关。当然,“ko.mapping”可以将我的C# POCOS翻译成具有observable属性的JS对象。这没问题,直到您想要JS方法的那一刻,难免会发生。
在以前的一个项目中,我实际上是通过编程方式向ko.mapped对象添加额外的方法。在那一点上,我质疑“ko.mapping”是否真的比解决问题更多。
我接受您对DRY问题的看法,但是,我无论如何都有不同的面向领域版本的POCO。例如,由UserController提供的“MyProject.Users.User”对象可能与“MyProject.Articles.User”非常不同。Users命名空间中的用户可能包含许多与用户管理相关的内容。Articles命名空间中的User对象可能只是一个简单的查找以指示文章的作者。我认为这种方法并不违反DRY原则,而是一种以两种不同方式看待相同概念的方法。
这需要更多的前期工作,但它意味着我有问题特定的用户表示形式,不会污染彼此的实现。
因此,对于Javascript视图模型也是如此。它们不是C# POCOs。它们是适合特定目的的概念的特定表述方式; 保存和操作客户端数据。虽然“ko.mapping”最初似乎可以提高生产率,但我认为最好手工制作专门针对客户端设计的特定视图模型。
顺便说一句,我使用与您完全相同的MVC3 / KnockoutJS策略。

1
我在使用 JavaScript 手工制作 VMs 方面与你持相同的看法。我仅在处理复杂模型或单调工作时使用 KO 映射。 - Judah Gabriel Himango

3
我们使用knockout Mapping来生成KO视图模型。
我们在一个独立的项目中拥有一个业务层,负责CRUD、报表、缓存和一些额外的“业务逻辑”。我们不会使用EF或类似的东西。目前,我们将c#类定义为MVC模型,并且我们的控制器调用业务层来构造通常在MVC应用程序中定义的模型。这些C#模型被序列化为JSON以供在我们的页面中使用。
由于我们在浏览器中所做的一切都是基于c#/JSON的,使用knockout,因此我们没有按照传统的MVC方式使用MVC模型-所有内容都作为JSON发布并序列化为c#,因此我们不使用MVC模型绑定、验证等。我们正在考虑将这些模型移动到我们的业务层中,以便可以独立于Web应用程序进行测试。
因此,我们将得到一个具有控制器和视图但没有模型的MVC应用程序-控制器将获得在业务层中定义的模型。我们对离开正常的MVC结构感到紧张,但基于KO/javascript的客户端与最初建立在DOM上的客户端根本不同,这是一个根本性的区别。
这种方法听起来可行吗?

我认为没有理由仅因为你要使用KO/javascript客户端就放弃模型。即使在提交后,它仍然为您提供绑定,并且通常您希望在第一次呈现时显示数据,即使您正在使用KO。个人而言,我会根据需要混合使用。 - Trevor de Koekkoek

1
这是一个老话题,但是在2014年(不幸的是),我仍然觉得这个问题非常重要。
我目前正在开发一个将MVC4与knockoutjs混合使用的项目。我遇到了一些困难,不知道应该在哪一方面处理哪些部分。我们还需要一种“SPA-ish”类型的架构,每个模块都有自己的页面,但是在该模块内部只有AJAX交互。还遇到了一些繁重的验证场景,并需要在每个模块内提供用户(和SEO)友好的URL。最终,我采用了以下概念,看起来效果不错:
基本的MVC和.NET方面的角色:
  • 处理认证和其他安全相关的事项。
  • 实现Web API接口,用于客户端调用(设置视图模型、从域中检索和映射数据等)。
  • 使用T4模板从我(预先存在的)C#视图模型生成knockout视图模型,还包括从.NET验证属性获得的knockout验证插件扩展。 (这是受this article启发的)。生成的视图模型易于扩展,并且可以使用几个“数据注释”类似的自定义或内置属性进行微调(例如DefaultValue、Browsable、DataType、DisplayFormat等)。这样就不会违反DRY(不要重复自己)原则(太多)。
  • 为每个子模块提供强类型但数据独立的部分视图模板(每个knockout视图模型)。由于C#视图模型上的属性名称与KO模型中的属性名称相同,因此我可以从专门为KO绑定编写的强类型帮助程序中受益等。
  • 类似于上一个点提供每个模块的主视图
  • 捆绑和缩小所有脚本和样式表。

基本的客户端角色:

  • 加载初始状态,将所有视图模型封装到一个模块页面中,考虑整个URL,并使用简单的路由解析器实现。
  • 处理历史记录,使用history.js。
  • 数据绑定,用户交互处理。
  • 发布相关部分的视图模型到服务器,并处理返回的数据(通常是更新一些视图模型)。

我希望这可以帮助任何感到在潮流技术世界中迷失的人。如果有任何想法,请随时在评论中发表任何问题或建议。


1

我现在正在处理一个混合了MVC3和knockouts的项目,我必须告诉你——这是一团糟... 在我看来,仅仅为了跟上潮流而强制使用某些模式是没有意义的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接