使用MVC,我如何设计视图,使其不需要控制器设置的变量的知识
本文关键字:不需要 控制器 设置 变量 知识 视图 MVC 使用 | 更新日期: 2023-09-27 18:07:23
假设我有一个理论上的MVC框架,它使用ViewData
对象将数据从控制器传递到视图。在我的控制器中,假设我有这样的代码(伪代码):
function GetClientInfo()
{
// grab a bunch of data from the database
var client = Database.GetClient();
var clientOrders = Database.GetClientOrders();
var clientWishList = Database.GetClientWishList();
// set a bunch of variables in the ViewData object
ViewData.set("client", client);
ViewData.set("clientOrders", clientOrders);
ViewData.set("clientWishList", clientWishList);
showView("ClientHomePage");
}
然后在ClientHomePage
视图中,我这样显示数据:
<p>Welcome back, [ViewData.get("client").FirstName]!</p>
<p>Your order history:</p>
<ul>
[Html.ToList(ViewData.get("clientOrders")]
</ul>
<p>Your wishlist:</p>
<ul>
[Html.ToList(ViewData.get("clientWishList")]
</ul>
这就是我所理解的MVC的样子(如果我错了,请纠正我)。这里的问题是视图中的魔法字符串。视图如何知道它可以从ViewData
对象中拉出什么对象,除非它知道控制器首先放在那里的是什么?如果有人对控制器中的一个魔法字符串进行重构,但忘记在视图中更改它,并获得运行时错误而不是编译时错误,该怎么办?在我看来,这似乎严重违反了关注点分离原则。
这就是我认为ViewModel可能派上用场的地方:
class ClientInfo
{
Client client;
List clientOrders;
List clientWishList;
}
然后控制器创建ClientInfo
的实例并将其传递给视图。ViewModel成为控制器和视图之间的绑定契约,视图不需要知道控制器在做什么,只要它假设控制器正在正确地填充ViewModel。起初,我认为这是MVVM,但阅读更多关于它的信息,似乎我想到的是更多的MVC-VM,因为在MVVM中,控制器不存在。
我的问题是,我在这里不理解MVC与MVVM吗?通过魔法字符串引用ViewData
中的变量真的不是那么糟糕的想法吗?如何确保控制器中的更改不会对视图产生负面影响?
你对MVC的理解是错误的,它代表模型视图控制器,但你在你的例子中缺少模型。这是被传递回View去做呈现的类型化实体。在ASP。Net MVC,你会使用类型化的视图,也键入视图内的模型,所以它是在编译时检查。这就消除了对魔法字符串的需求(你问题的第二部分)。
在MVVM中,你有模型视图视图模型。这是一种通过View将ViewModel直接绑定到UI层的方法,在WPF中使用得很多。它取代了对控制器的需求,它通常是与UI的一对一映射。它只是一种替代机制,可以解决相同的问题(抽象和关注点分离),但更适合于该技术。
这里有一些有用的信息可以帮助理解它们的区别。
使用强类型视图的最佳方法
模型:
public class ContentPage
{
public string Title { get; set; }
public string Description { get; set; }
}
public class ContentPagesModel
{
public ContentPage GetAboutPage()
{
var page = new ContentPage();
page.Title = "About us";
page.Description = "This page introduces us";
return page;
}
}
控制器:
public ActionResult About()
{
var model = new ContentPagesModel();
var page = model.GetAboutPage();
return View(page);
}
视图:
@model Experiments.AspNetMvc3NewFeatures.Razor.Models.ContentPage
@{
View.Title = Model.Title;
}
<h2>About</h2>
<p>
@Model.Description
</p>
更多细节请查看这里
使用字符串作为ViewData的键的情况-是的,如果有人重构代码,将会有很多例外。
听起来你对MVC的理解很旧,可能是基于MVC 1。在过去的几年里,事情发生了巨大的变化。
现在我们有了强类型的视图模型,并且我们有能力在视图中使用表达式,默认情况下,这些表达式不会在编译时进行验证,但是它们可以用于调试目的(尽管这会大大降低构建速度)。
更重要的是,我们不再通过ViewDate传递模型数据(好吧,不是直接…它仍然以这种方式传递,但框架隐藏了它)