在一个请求中渲染具有相同模型的多个局部视图

问题描述

假设我有3个局部视图,所有局部视图都采用相同的模型,并且类似地应同时渲染/更新。即

<div id="Partial_view1">
    @{ await Html.RenderPartialAsync("partialview1",Model); }
</div>
<div class="Partial_view2">
    @{ await Html.RenderPartialAsync("partialview2",Model); }
</div>
<div class="Partial_view3">
    @{ await Html.RenderPartialAsync("partialview3",Model); }
</div>

当前,当我想使用jQuery和AJAX更新部分视图时,通常我分别使用父div,URL和可能的ID调用以下函数:

var updatePartialView = function (url,data,hook) {
    $.ajax({
        url: url,type: 'GET',data: data,success: function (response) {
            hook.html(response);
        }
    });
}

可能看起来像这样:

helper.updatePartialView('/Controller',2,$('#Partial_view1'))

然后,控制器通常会返回局部视图结果,自然会返回局部视图和模型,该模型嵌套在局部视图的div之下。

//From controller
return PartialView("partialview1",Model);

我想减少服务器的有效负载,因此我对执行3个几乎相同的调用不感兴趣。因此,为什么要理解,如果我有某种方式可以从中获取模型控制器,然后在jquery中填充3个局部视图。

预先感谢

解决方法

由于三个局部视图在同一页面上,因此您只需使用return View("MainPage",model)即可使用更新后的模型来更新主页,而不是使用return PartialView("PartialViewName",model)

但是这种方式有一个缺点,如果在剃刀视图中使用“布局”,它将重复显示导航栏。

Index.cshtml:

@model IEnumerable<Test>
<div id="view_all">
    <div id="Partial_view1">
        @{ await Html.RenderPartialAsync("partialview1",Model); }
    </div>
    <div class="Partial_view2">
        @{ await Html.RenderPartialAsync("partialview2",Model); }
    </div>
    <div class="Partial_view3">
        @{ await Html.RenderPartialAsync("partialview3",Model); }
    </div>
    <input type="button" onclick="Update()" value="Update" />
</div>
@section Scripts
{
    <script>
        function Update() {
            updatePartialView('/Home/Update',2)
        }    
        var updatePartialView = function (url,data) {
            $.ajax({
                url: url+"?id="+data,type: 'GET',success: function (response) {
                    $('#view_all').html(response);
                }
            });
        }
    </script>
}

控制器:

public class HomeController : Controller
{
    private List<Test> model = new List<Test>()
        {
            //....
        };

    public IActionResult Index()
    {
        return View(model);
    }
    public IActionResult Update(int id)
    {
        //change the model by yourself
        var test2 = model.Where(a=>a.Id==id).FirstOrDefault();
        test2.Number = 9;
        model[0].Test1.Category = "aaaaaaaa";
        model[2].Test2.Age = "34343434";

        return View("Index",model);
    }
}

第二个选项:我认为您可以自定义一个RenderRazorViewToString函数,该函数可以将视图解析为字符串,并且如下所示:

型号:

public class Test
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Number { get; set; }
    public Test1 Test1 { get; set; }        
    public Test2 Test2 { get; set; }        
}
public class Test1
{
    public string Category { get; set; }
}
public class Test2
{
    public string Age { get; set; }
}

Index.cshtml:

@model IEnumerable<Test>
//...
<input type="button" onclick="Update()" value="Update" />

@section Scripts
{
    <script>
        function Update() {
            updatePartialView('/Home/Update',2)
        }
        
        var updatePartialView = function (url,success: function (response) {
                    $('#Partial_view1').html(response.view1);
                    $('.Partial_view2').html(response.view2);
                    $('.Partial_view3').html(response.view3);
                }
            });
        }
    </script>
}

partialview1.cshtml:

@model IEnumerable<Test>
<h1>Test</h1>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Number)
            </th>
            <th>
                @Html.DisplayNameFor(model => model.Name)
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Number)
                </td> 
                <td>
                    @Html.DisplayFor(modelItem => item.Name)
                </td>               
            </tr>
        }
    </tbody>
</table>

partialview2.cshtml:

@model IEnumerable<Test>
<h1>Test1</h1>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Test1.Category)
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Test1.Category)
                </td>
            </tr>
        }
    </tbody>
</table>

partialview3.cshtml:

@model IEnumerable<Test>
<h1>Test2</h1>
<table class="table">
    <thead>
        <tr>
            <th>
                @Html.DisplayNameFor(model => model.Test2.Age)
            </th>
        </tr>
    </thead>
    <tbody>
        @foreach (var item in Model)
        {
            <tr>
                <td>
                    @Html.DisplayFor(modelItem => item.Test2.Age)
                </td>
            </tr>
        }
    </tbody>
</table>

控制器:

public IActionResult Update(int id)
{
    //change your model by yourself
   
    //pass the updated model to the partial view
    var view1 = Helper.RenderRazorViewToString(this,"partialview1",model);
    var view2 = Helper.RenderRazorViewToString(this,"partialview2",model);
    var view3 = Helper.RenderRazorViewToString(this,"partialview3",model);
    return Json(new { view1 = view1,view2 = view2,view3 = view3 });
}

RenderRazorViewToString方法:

public class Helper
{
    public static string RenderRazorViewToString(Controller controller,string viewName,object model = null)
    {
        controller.ViewData.Model = model;
        using (var sw = new StringWriter())
        {
            IViewEngine viewEngine =
                controller.HttpContext.RequestServices.GetService(typeof(ICompositeViewEngine)) as
                    ICompositeViewEngine;
            ViewEngineResult viewResult = viewEngine.FindView(controller.ControllerContext,viewName,false);

            ViewContext viewContext = new ViewContext(
                controller.ControllerContext,viewResult.View,controller.ViewData,controller.TempData,sw,new HtmlHelperOptions()
            );
            viewResult.View.RenderAsync(viewContext);
            return sw.GetStringBuilder().ToString();
        }
    }
}

结果: enter image description here

顺便说一下,这三个全景视图取决于同一模型,为什么将它们作为一个局部视图放在一起?

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...