【问题标题】:Retrieving Data from Model (or Controller) in MVC Page从 MVC 页面中的模型(或控制器)中检索数据
【发布时间】:2013-11-10 01:37:12
【问题描述】:

我希望能提供一些关于实现以下目标的最合适方法的指导。

我的 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
}

我创建了以下视图:
视图\桌面\Index.cshtml
视图\桌面\_PeoplePartial.cshtml
视图\桌面\_PlacesPartial.cshtml

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

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

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

【问题讨论】:

  • 看看返回的stringJson。软刷新只需使用 AJAX 并调用 Get*()(然后将其推送到您的视图中)。如果您不想在 AJAX 回调中执行 UI 工作,也可以返回 PartialViewResult/PartialView

标签: c# asp.net asp.net-mvc-4 razor asp.net-ajax


【解决方案1】:

Source Code for the below answer

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

【讨论】:

  • 感谢 Brad(以及其他人的贡献)。 PartialViewResult 方法感觉最适合我的需要。 QQ 虽然...虽然我非常乐意使用此处提供的信息并手动编写代码,但您还是提供了一个指向 GitHub 源代码的链接。我已经点击了那个链接,可以在我的浏览器中浏览文件,但是有没有办法从 GitHub 下载那个源代码?
  • @NeilW:如果你有 github 帐户,只需在本地 fork 并执行 git pull。如果没有(或者您不想要),请转到存储库的 root 并查找 Download Zip(向右)。它将包含那个(以及其他几个)项目。
  • 知道了,布拉德。再次感谢。
【解决方案2】:

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

编辑:

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

【讨论】:

    【解决方案3】:

    您的控制器可能应该返回 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 的东西/应用程序/页面

    【讨论】:

    • 尽管我同意(在我的原始评论中提到 JSON)如果 OP 已经达到已经创建部分视图的程度,那么他/她应该真的只是再次返回部分视图(恕我直言)。否则,请全力以赴,只需将 JSON 放入索引调用中(并在 AJAX 调用中再次获取它),然后使用诸如 knockoutjs 之类的东西来“连接它”。如果不这样做,则在两个地方有 UI 逻辑:部分代码和 AJAX 代码。
    猜你喜欢
    • 1970-01-01
    • 2011-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-05
    • 1970-01-01
    • 2011-05-29
    相关资源
    最近更新 更多