有什么好的理由不在核心 MVC 中使用 ViewComponent 而不是 Partial View 吗?

问题描述 投票:0回答:3

我是 MVC 新手,决定从 .net-core 开始,所以我对 core 与旧版本的差异不太了解。我确实找到了下面的问题,它提供了一些见解,但并没有帮助我决定是否可以基本上忽略部分视图。

为什么我们应该使用 MVC 6 功能视图组件而不是部分视图:有什么区别?

我的问题很简单 - 如果我可以用 ViewComponent 做一些事情,有什么好的理由不这样做吗?

非常感谢!

下面提供了上下文示例。

主视图调用:

视图组件:

<div class="modal-body" ID="modalPersonInner">
       @await Component.InvokeAsync("CreatePerson", new Person())
</div>

与部分视图:

<div class="modal-body" ID="modalPersonInner">
    @{ await Html.RenderPartialAsync("People/CreatePartialView", new Person());}
</div>

Javascript(personCreateForm 是部分视图/视图组件中的表单):

 var submitPersonCreate = function(evt) {

        evt.preventDefault();
        if ($(this).valid())
        {
            $.ajax({
                type: "POST",
                url: '@Url.Action("CreatePartial", "People")',
                data: $('#personCreateForm').serialize(),
                success(data) {
                    if (data === true)
                        window.location.reload();
                    else
                        $('#modalPersonInner').html(data);
                }
            });
        }

        return false;
    }
$('#personCreateForm').submit(submitPersonCreate);

控制器代码:

  public async Task<IActionResult> CreatePartial(
        [Bind("AddressLine1,AddressLine2,AddressLine3,AddressLine4,City,Country,Email,Forename,MobileNumber,Postcode,Region,Surname,TelephoneNumber")] Person person)
    {
        if (ModelState.IsValid)
        {
            _context.Add(person);
            await _context.SaveChangesAsync();
            return Json(true);
        }
        //PARTIAL VIEW VERSION
        //return PartialView("People/CreatePartialView",person);

        //VIEWCOMPONENT VERSION
        return ViewComponent("CreatePerson", person);
    }

ViewComponent代码:

 public class CreatePersonViewComponent : ViewComponent
    {
        private readonly AppDbContext db;

        public CreatePersonViewComponent(AppDbContext context)
        {
            db = context;
        }

        public async Task<IViewComponentResult> InvokeAsync(Person person )
        {

            return View(person ?? new Person());
        }

    }

最后是 Razor 页面,两者相同:

@model Person

<form ID="personCreateForm">
    <div class="form-horizontal">
        <h4>Customer</h4>
        <hr />
        <div asp-validation-summary="ModelOnly" class="text-danger"></div>
        <div class="form-group">
            <label asp-for="Forename" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Forename" class="form-control" />
                <span asp-validation-for="Forename" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="Surname" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Surname" class="form-control" />
                <span asp-validation-for="Surname" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="Country" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Country" class="form-control" Value="UK" />
                <span asp-validation-for="Country" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="Region" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Region" class="form-control" />
                <span asp-validation-for="Region" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="City" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="City" class="form-control" />
                <span asp-validation-for="City" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="AddressLine1" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="AddressLine1" class="form-control" />
                <span asp-validation-for="AddressLine1" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="AddressLine2" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="AddressLine2" class="form-control" />
                <span asp-validation-for="AddressLine2" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <label asp-for="Postcode" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Postcode" class="form-control" />
                <span asp-validation-for="Postcode" class="text-danger" />
            </div>
        </div>

        <div class="form-group">
            <label asp-for="Email" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="Email" class="form-control" />
                <span asp-validation-for="Email" class="text-danger" />
            </div>
        </div>

        <div class="form-group">
            <label asp-for="MobileNumber" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="MobileNumber" class="form-control" />
                <span asp-validation-for="MobileNumber" class="text-danger" />
            </div>
        </div>



        <div class="form-group">
            <label asp-for="TelephoneNumber" class="col-md-2 control-label"></label>
            <div class="col-md-10">
                <input asp-for="TelephoneNumber" class="form-control" />
                <span asp-validation-for="TelephoneNumber" class="text-danger" />
            </div>
        </div>
        <div class="form-group">
            <div class="col-md-offset-2 col-md-10">
                <input type="submit" value="Create" class="btn btn-default" />
            </div>
        </div>
    </div>
</form>
c# asp.net-mvc asp.net-core asp.net-core-mvc
3个回答
24
投票

这是一个非常好的问题。 是的,在某些情况下,使用分部视图实现代码比使用视图组件更好。 如果视图组件不会有任何明显数量的逻辑(如您的示例中的情况),那么您应该使用分部视图。

视图组件是划分逻辑的好方法,在某些方面可以被视为包含其自身逻辑的部分视图。 但是,如果没有任何逻辑需要与部分视图分隔,那么最好不要使用视图组件。 在这种情况下,使用视图组件会增加编码复杂性(还有另一个地方可以查看代码如何工作),但不会提供任何真正的好处。 一般来说,您应该仅将代码复杂性增加到从增加的复杂性中获得的收益大于该复杂性的“成本”的程度。

我希望这听起来不太理论化。 它基本上可以归结为:如果您想要将某个逻辑与分部视图打包在一起,以便您可以反复使用该组件,则使用视图组件,但如果没有任何逻辑需要您将其打包然后使用局部视图。


0
投票

View Components 似乎(截至 2016 年 7 月)仍然存在一些与 javascript 和 css 加载相关的未解决问题。请检查: https://blog.mariusschulz.com/2015/11/26/view-components-in-asp-net-mvc-6


0
投票

我的观点是。

如果您有通用的 html,没有特殊的逻辑、api 或 dB 要求,并且您需要的是页面通用的并且可以使用页面视图模型数据。然后使用“部分”视图。引导模式和向导导航按钮是我使用它们的很好的例子。 当我想封装一些对页面本身几乎没有依赖性的 html、逻辑、dB 和/或 api 调用时,我使用

viewcomponents

。但需要做相当多的工作来获取数据并呈现自身。本质上独立于页面视图模型并且是独立的。菜单和信息标题就是我的例子。只需在您的页面中添加一行内容即可!一次编写,到处使用。 有人还记得

ActionPartials

吗?哈哈

© www.soinside.com 2019 - 2024. All rights reserved.