我正在ASP.NET MVC应用程序中填充一个视图。根据用户输入,页面后必须加载大量数据,因此我正在进行Ajax调用以获取此数据。我不想重新加载页面来获取数据。
更正我,如果我使用了错误的术语(过去一周来我已经看过一些),但是从Ajax加载的数据是幂等,它将用于显示只要;用户将不会更新数据作为输入。
我想知道的是,是否仍应在视图模型中定义在Ajax调用中获取的数据字段?
考虑以下代码:
ProfileViewModel.cs
public class ProfileViewModel
{
// populated on initial request
string Name { get; set; }
IEnumerable<Subscriber> Subscribers { get; set; }
// the data in question - keep it here?
IEnumerable<Post> SubscriberPosts { get; set; }
}
ProfileController.cs
public class ProfileController
{
public ActionResult Index()
{
return View( new ProfileViewModel()
{
Name = GetUserName(),
Subscribers = GetAllSubscribers()
});
}
public GetSubscriberPosts( string id )
{
// do stuff to get posts
}
}
ProfileView.cshtml
@using MyNamespace.Models.ProfileViewModel
<div id="Profile">
<h1>@Model.Name</h1>
<ul>
@{
foreach(var subscriber in @Model.Subscribers)
{
<li><a onclick="PreviewSubscriberPosts('@subscriber.UserID')">@subscriber.Name</a></li>
}
}
</ul>
</div>
<div id="SubscriberPostsPreview">
<!-- show some stuff here based on the selected subscriber -->
</div>
<script>
$("#SubscriberPostsPreview").hide();
function PreviewSubscriberPosts(userID) {
// get the subsribers posts
$.get("/Path/To/GetSubscriberPosts", { id = userID }, function (data) {
// add data to the document
});
$("#SubscriberPostsPreview").show();
}
</script>
我可以通过两种方式看到我的问题的答案,但是请确保有人对这个问题有更好的答案。
(顺便说一句,据我所知,在视图模型中定义的属性既可以表示要显示的数据,也可以表示要从用户输入获取的数据)
答案A
视图模型表示要在视图中显示的数据,因此请在视图模型中全部定义。
答案B
由于必须在页面之后使用Ajax加载数据,并且用户不会更改数据,因此没有理由在视图模型中定义数据。
我倾向于答案B,但正在寻找其他人的输入。
答案 0 :(得分:2)
视图模型的目的是封装视图中正在使用的数据。无论是在页面加载视图中使用它还是对ajax调用的响应,这都没有关系。如果涉及的数据像一个字符串一样简单,或者仅仅是一个整数列表/数组,那么我可能就不用担心。但是,如果涉及的内容远不止于此,则建议将其封装在vm中。
如果要发送的请求与视图模型相差很大,那么我建议为其创建一个新模型。这通常称为请求模型。术语“请求模型”通常用于描述api请求,但此处存在相同的基本思想。您有一个发送到服务器的请求,并且该请求涉及一组稍微复杂的数据。因此,您可以将数据封装在模型中,并让模型绑定发挥其魔力。这也将使服务器端代码更加整洁和易于维护。
请求模型和视图模型都是DTO,即数据传输对象(另请参见POCO)。这些对象通常没有用户定义的构造函数(尽管在需要时可以可以),但是它们对于创建更清晰的代码非常方便,并且易于阅读和维护。
答案 1 :(得分:2)
在这种情况下,您将有2个不同的ViewModel。一个用于初始索引请求,另一个用于ajax请求。 SubscriberPosts仅是ajax请求ViewModel的属性。通常对于Ajax请求,我只是将ViewModel保留为匿名对象,而不是定义类。