简体   繁体   English

ASP.NET Core MVC - 无法使用视图返回模型

[英]ASP.NET Core MVC - Trouble returning model with view

I'm trying to provide user input from the view, call an action method from the controller, using the input to filter the model, then return the same view with the filtered model. 我正在尝试从视图中提供用户输入,从控制器调用操作方法,使用输入来过滤模型,然后使用过滤的模型返回相同的视图。

App View: 应用视图:

<div class="form-group">
    <div class="row">
        <div class="col-xs-3">
            Enter your budget, and we'll show you all the movies you can afford:
        </div>
        <div class="col-xs-3">
            <input type="text" class="form-control" id="budget" />
        </div>
        <div class="col-xs-3">
            <input type="submit" class="btn" id="budgetSubmit" onclick="budgetFilter()" />
        </div>
    </div>
    <div class="row">
        <div class="col-xs-3 col-xs-offset-3">
            <label id="budgetValidation"></label>
        </div>
    </div>
    <br />
    <table class="table" id="budgetTable">
        <thead>
            <tr>
                <th>
                    @Html.DisplayNameFor(model => model.Title)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.ReleaseDate)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Genre)
                </th>
                <th>
                    @Html.DisplayNameFor(model => model.Price)
                </th>
                <th></th>
            </tr>
        </thead>
        <tbody>
            @foreach (var item in Model)
            {
                <tr>
                    <td>
                        @Html.DisplayFor(modelItem => item.Title)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.ReleaseDate)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Genre)
                    </td>
                    <td>
                        @Html.DisplayFor(modelItem => item.Price)
                    </td>
                </tr>
            }
        </tbody>
    </table>

<script>
function budgetFilter() {
    let budget = $("#budget").val();
    if (budget != "") {
        $.get("../Movies/App?budget=" + budget, function (response) {
        })
            .fail(function () {
                $("#budgetValidation").html("No films match your budget")
            });
    }
    else {
        $("#budgetValidation").html("Please enter a budget");
    }
 </script>

Controller: 控制器:

        public async Task<IActionResult> App(decimal budget)
        {
            var movie = await _context.Movies.Where(m => m.Price <= 
            budget).ToListAsync();
            if (movie == null)
            {
                return NotFound();
            }
            return View(movie);
        }

I've debugged the controller and know it's working as intended. 我调试了控制器并知道它按预期工作。 My understanding is that clicking budgetSubmit fires budgetFilter, which calls the App action method in the controller, which filters the movies model, then renders the same App view, but with the model I need to populate the table. 我的理解是单击budgetSubmit会触发budgetFilter,它调用控制器中的App动作方法,过滤电影模型,然后呈现相同的App视图,但是我需要填充表格。 It does work if I navigate directly to a url like "localhost:xxxx/Movies/App?budget=20". 如果我直接导​​航到像“localhost:xxxx / Movies / App?budget = 20”这样的网址,它确实有用。 But not through the button click. 但不是通过按钮点击。

I understand I don't actually need to render the page all over again, but I don't see why the way I did it doesn't work and want to figure it out before moving on. 我知道我实际上并不需要再次渲染页面,但是我不明白为什么我这样做的方式不起作用并希望在继续之前弄明白。 How would you: 1. Do it the way I tried to do it, correctly, and 2. Do it a better way. 你会怎样:1。按照我尝试的方式,正确地做到这一点,并且2.做得更好。

Thanks. 谢谢。

  1. The simpliest way is just redirrect on url with budget value. 最简单的方法是在具有预算值的网址上重新编写。 Perfect works for pet\\home projects. 适合宠物\\家居项目的完美作品。
<script>
    function budgetFilter() {
        let budget = $("#budget").val();
        if (budget != "") {
            window.location.href = `/Home/App?budget=${budget}`;
        } else {
            $("#budgetValidation").html("Please enter a budget");
        }
    }
</script>
  1. The right way is do the same things as it does guys from Microsoft: https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/sort-filter-page 正确的方法是做与微软公司相同的事情: https//docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/sort-filter-page

Your best bet might be to return a partial view from your controller 您最好的选择可能是从控制器返回局部视图

public async Task<IActionResult> App(decimal budget)
    {
        var movie = await _context.Movies.Where(m => m.Price <= 
        budget).ToListAsync();
        if (movie == null)
        {
            return NotFound();
        }
        return PartialView(movie);
    }

Port the dynamic bit of your view out into a partial 将视图的动态位移到局部

<div id="budget"> 
  <table class="table" id="budgetTable">
   ...
  </table>
</div>

In the callback of your ajax 在你的ajax的回调中

    $.get("../Movies/App?budget=" + budget, function (response) {
       $("#budget").html(response);
    })

This is sensible if you'd like fresh data upon each request. 如果您在每次请求时都喜欢新数据,这是明智的。 If you just want to return the full payload on the first call and filter client side I'd suggest looking at this 如果您只想在第一次调用和过滤客户端时返回完整的有效负载,我建议您查看此内容

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM