MVC 电影教程和强类型视图
Posted
技术标签:
【中文标题】MVC 电影教程和强类型视图【英文标题】:MVC Movie Tutorial And Strongly Typed Views 【发布时间】:2013-11-15 03:23:54 【问题描述】:我正在尝试遵循 MVC 电影教程并了解到目前为止的所有内容。我只是对强类型视图有些困惑。
我想我理解他们的目的。我只是不确定他们将如何在本教程之外的现实生活场景中工作。
例如,需要从多个表中获取数据的强类型视图。
假设教程中的电影应用程序有另一个名为 cmets 的表。
我们希望在每部电影上显示 cmets。
强类型视图如何访问两个不同的模型(我认为它不能)。处理这种情况的正确方法是什么。
(我已经搜索并无法真正找到我理解的答案 - 此线程中的评论 What is strongly-typed View in ASP.NET MVC 涉及该主题,但我真的不明白他的答案)
如有任何帮助,我们将不胜感激。谢谢
【问题讨论】:
【参考方案1】:强类型模型(在本例中为“视图模型”)从多个模型中提取数据是完全可以的。一个简单的示例可能如下所示:
public class SomeViewModel
public List<Employee> Employees get; set;
public List<Job> Jobs get; set;
现在,在您的控制器中,您可以按照您认为合适的方式填充这些集合中的每一个:
public ActionResult Index()
var model = new SomeViewModel();
model.Employees = // ... fetch from database.
model.Jobs = // ... fetch from database.
return View(model);
现在,在您看来,您可以像这样访问它们:
@model SomeViewModel
@html.DisplayFor(m => m.Employees)
@Html.DisplayFor(m => m.Jobs)
我不太记得 MVC 电影教程,所以这可能已经涵盖了。如果没有,下一步是为每一个创建一个显示模板,以便正确显示集合。
为此,请按以下步骤操作:
-
在视图的当前文件夹中创建一个
DisplayTemplates
文件夹(例如,如果您的视图是Home\Index.cshtml
,则创建文件夹Home\DisplayTemplates
)。
在该目录中创建一个名称与您的模型匹配的强类型视图(即在上面的示例中,您将创建两个视图,分别称为 Employee.cshtml
和 Job.cshtml
)。
那么这些模板可能看起来像这样:
Employee.cshtml:
@model Employee
@Html.DisplayFor(m => m.Id)
@Html.DisplayFor(m => m.Name)
Job.cshtml:
@model Job
@Html.DisplayFor(m => m.Id)
@Html.DisplayFor(m => m.Name)
显示模板及其对应的编辑器模板足够聪明,知道如何处理集合,因此将为集合的每个成员调用这些模板,为每个项目呈现模板的内容。
对于它的价值,我清楚地记得当我开始使用 MVC 时,试图弄清楚视图模型到底是什么是多么令人困惑。从最初设置官方实体框架教程的方式来看,它并没有说清楚(至少对我来说)。因此,考虑到这一点,请阅读 this 和 this,因为这两个答案对我来说都清楚了很多。
【讨论】:
非常感谢 - 我还在这里,非常感谢您的时间。只是给它一个很好的阅读试图让我明白它。 @loveforfire33 不客气,不用着急。那里有很多不同的概念。 好的,通读一遍,它有点像大脑融化器!据我了解,我最终会得到三个模型。员工、工作和 SomeViewModel。 SomeViewModel 将只有我需要该特定页面的变量 - 比如说 jobList。然后我将创建一个 jobList 控制器,在其中我将选择 SomeViewModel 作为模型类并从数据库中获取数据。然后,我将为 SomeViewModel 控制器创建一个强类型视图,并添加类似于您的示例 someviewmodel 视图代码的代码。这听起来对吗? @loveforfire33SomeViewModel would only have the variables i need for that specific page - say jobList
- 这部分是正确的。你也说对了,你最终会得到至少 3 个模型。至于控制器,这部分不太对。通常,您根据控制器提供的分组功能创建控制器。例如,您可能有一个 CustomerController
来处理显示客户列表并查看这些客户的详细信息。
@loveforfire33 每个客户可以有多个订单,但这并不意味着您需要OrdersController
,因为显示客户订单的功能对于成为CustomerController
的一部分是有意义的。
【参考方案2】:
当我开始使用 MVC 时,我也对强类型视图概念感到困惑!
然后,在额头上打了几拳之后,我意识到创建绑定到模型的视图的想法并不一定意味着模型将代表数据库中的表或映射器中的实体。
问题在于,在模型中,您可以对视图中可能需要的任何必要数据类型进行分组,因此当在视图中访问模型时,您可以通过强类型方式获得所需的所有数据。
以你所说的电影为例,我将为强类型视图创建的模型类似于:
public class MovieModel
public int MovieId get; set;
public string MovieName get; set;
public IEnumerable<CommentModel> MovieComments get; set;
public class CommentModel
public int CommentId get; set;
public int CommentText get; set;
所以在我看来,我可以像这样循环浏览我的电影的 cmets:
@model MovieModel
foreach(var comment in Model.MovieComments)
//Do somthing with your comments
当然,首先在控制器上填充你的 MovieModel,让我们说一下编辑操作:
public ActionResult Edit(int id)
var _Movie = Movie.GetMovieById(id);
var _Comments = Comments.GetCommentsByMovieId(id);
var _MovieModel = new MovieModel();
_MovieModel.MovieId = _Movie.MovieId;
_MovieModel.MovieName = _Movie.MovieName;
_MovieModel.MovieComments = (from Comment _Comment in _Comments select new
CommentModel CommentId = _Comment.CommentId , CommentText = _Comment.CommentText ).ToList();
return View(_MovieModel);
当然,您可以直接在 MovieModel 类上使用 cmets 实体,这样您就不需要 CommentModel,它会是这样的:
public class MovieModel
public int MovieId get; set;
public string MovieName get; set;
public IEnumerable<Comment> MovieComments get; set;
而你的行为如下:
public ActionResult Edit(int id)
var _Movie = Movie.GetMovieById(id);
var _Comments = Comments.GetCommentsByMovieId(id);
var _MovieModel = new MovieModel();
_MovieModel.MovieId = _Movie.MovieId;
_MovieModel.MovieName = _Movie.MovieName;
_MovieModel.MovieComments = _Comments;
return View(_MovieModel);
与前一种情况一样,在同一个强类型视图上只得到一个模型和来自不同表的数据,尽管有些人可能会说你这样做违反了一些 MVC 概念是完全有可能的......
希望对你有所帮助
【讨论】:
当您不需要时,您无需在视图中使用foreach
。使用 Html.*
助手可以让您的视图保持干净且没有逻辑(这是它们应该的样子)。
你说得对,但我只是想清楚你的数据是如何在视图中的 Model 对象中强类型化的以上是关于MVC 电影教程和强类型视图的主要内容,如果未能解决你的问题,请参考以下文章