2

对于实现以下目标的最合适方法,我将不胜感激。

我的 MVC 应用程序将有一个主视图(桌面),其中显示 2 个单独的列表(人物、地点)。我想让用户能够独立刷新每个列表,而无需刷新整个页面。

因此,我创建了一个控制器,它将加载“索引”视图并传入模型“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
}

我创建了以下视图:
Views\Desktop\Index.cshtml
Views\Desktop\_PeoplePartial.cshtml
Views\Desktop\_PlacesPartial.cshtml

然后将部分视图包含在索引视图中。

所以,我现在想做的是在每个局部视图上添加一个“刷新”按钮。当按下刷新按钮时,页面应该进行调用:例如 Model.GetPersons 以检索强类型 Person 对象的可枚举列表,然后我想使用 Razor 语法显示表中每个 Person 对象的属性.

也许,我完全走错了路。最初的要求(一页,两个列表,独立刷新)看起来相当简单,可能是一个常见的场景,所以任何关于我应该遵循的模式的建议将不胜感激。

4

3 回答 3

1

您的 ViewModel 不应该负责从数据库中检索项目。相反,您的控制器应该通过 ViewModel 将项目传递给视图。这是一个例子:

视图模型

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 访问人员。

编辑:

我想说你也可以不使用两个局部视图并在索引视图中做所有事情,除非你打算重用局部视图。

于 2013-10-30T13:30:55.027 回答
1

以下答案的源代码

设置您将使用 AJAX 获取的调用(而不是IEnumerable<T>使用 a 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>

阿贾克斯:

<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>
于 2013-10-30T13:46:25.367 回答
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>

这真的更多是为了说明。与其使用 .append() 手动附加 HTML,不如使用 javascript 模板系统,或者如果您要在站点的其余部分执行类似的操作,则可能需要使用类似 knockout.js 或backbone.js 的东西/应用程序/页面

于 2013-10-30T13:25:33.653 回答