对于实现以下目标的最合适方式,我将不胜感激。
我的MVC应用程序将有一个主视图(桌面),它显示2个单独的列表(人物,地点)。我希望能够让用户独立刷新每个列表,而无需刷新整个页面。
所以,我创建了一个Controller,它将加载“Index”视图并传入一个模型“DesktopViewModel”。
DesktopViewModel
public IEnumerable<Person> GetPersons()
{
// Retrieve Person data from database and return to caller
}
public IEnumerable<Place> GetPlaces()
{
// Retrieve Place data from database and return to caller
}
我创建了以下视图:
浏览次数:\桌面\ Index.cshtml
浏览次数:\桌面\ _PeoplePartial.cshtml
视图\桌面\ _PlacesPartial.cshtml
然后,部分视图会包含在索引视图中。
所以,我现在要做的是在每个局部视图上添加一个“刷新”按钮。按下该刷新按钮时,页面应该拨打电话:例如Model.GetPersons检索强类型Person对象的可枚举列表,然后我想使用Razor语法显示表中每个Person对象的属性。
也许,我完全以错误的方式解决这个问题。最初的要求(一页,两个列表,独立刷新)看起来相当简单,可能是一个常见的场景,因此对我应遵循的模式的任何建议都将非常感激。
答案 0 :(得分:1)
您的ViewModel不应负责从数据库中检索项目。相反,您的Controller应通过ViewModel将项目传递给View。这是一个例子:
<强>视图模型强>
public class DesktopViewModel
{
public IEnumerable<Person> Persons { get; set; }
public IEnumerable<Place> Places { get; set; }
}
控制器(部分)
public ActionResult Index()
{
// get your data
var model = new DesktopViewModel();
// set your data to the ViewModel
}
然后在您看来,您可以通过Model.Persons访问人员。
编辑:
我会说你也可以在不使用两个部分视图的情况下取消并在索引视图中执行所有操作,除非您计划重新使用部分视图。
答案 1 :(得分:1)
Source Code for the below answer
设置您使用AJAX获取的通话(而不是IEnumerable<T>
使用PartialViewResult
(因为您已经定义了_*Partial.cshtml
:
//
// GET: /Desktop/GetPersons
public PartialViewResult GetPersons()
{
var persons = this.desktopService.GetPersons()
.OrderBy(x => Guid.NewGuid()); // randomize to make it look like a refresh
return PartialView("_PeoplePartial", persons);
}
//
// GET: /Desktop/GetPlaces
public PartialViewResult GetPlaces()
{
var places = this.desktopService.GetPlaces()
.OrderBy(x => Guid.NewGuid()); // randomize to make it look like a refresh
return PartialView("_PlacesPartial", places);
}
(请原谅desktopService
它只是获取数据的通用方法)
接下来,添加一个刷新按钮和一些jQuery代码,以便动态获取这些值:
按钮和内容:
<div class="row">
<div class="col-md-3">
<!-- we add "get-persons" class so we can bidn to it with jQuery -->
<button class="btn bt-default pull-right get-persons" data-loading-text="Loading...">Refresh People</button>
</div>
<!-- we also add the "persons" class so we have a target to place
the new content into -->
<div class="col-md-3 text-center persons">
@{ Html.RenderPartial("_PeoplePartial", Model.People); }
</div>
<!-- same things as above, just in referse order: "places" and "get-places" -->
<div class="col-md-3 text-center places">
@{ Html.RenderPartial("_PlacesPartial", Model.Places); }
</div>
<div class="col-md-3">
<button class="btn bt-default get-places" data-loading-text="Loading...">Refresh Places</button>
</div>
</div>
AJAX:
<script>
$(function () {
$(document).on('click', '.get-persons', function (e) {
var $btn = $(this).prop('disabled', !0);
$.ajax('@Url.Action("GetPersons", "Desktop")').done(function (html) {
$('.persons').html(html);
}).always(function(){
$btn.prop('disabled', !1);
});
e.preventDefault();
}).on('click', '.get-places', function (e) {
var $btn = $(this).prop('disabled', !0);
$.ajax('@Url.Action("GetPlaces", "Desktop")').done(function (html) {
$('.places').html(html);
}).always(function () {
$btn.prop('disabled', !1);
});
e.preventDefault();
});
});
</script>
答案 2 :(得分:0)
您的控制器应该返回JSON,而不是部分视图。
public JsonResult GetPersons()
{
IList<Person> people = GetPeople();
return Json(people);
}
然后在你的javascript中,你可以做类似的事情(假设你正在使用jQuery):
$('#refresh-person-button').on('click', function() {
$.getJSON('/controller/getpersons', function(res) {
$.each(res, function() {
$('#person-container ul').append('<li>' + res.FirstName + '</li>');
});
});
});
最后,在你的HTML中:
<div id="person-container">
<ul></ul>
</div>
这更像是为了说明。你可能想要使用javascript模板系统,或者像knockout.js或backbone.js这样的东西,而不是用你的网站的其他部分做类似的事情。 /应用程序/网页