使用MVC Core的Ajax.ActionLink替代方案

7
在MVC5中,@Ajax.ActionLink非常有用,可以更新部分视图,而不必重新加载整个视图。显然,在MVC6中不再支持此功能。
我尝试使用@Html.ActionLink,如下所示,但它无法更新表单,只会返回部分视图:
视图:
@Html.ActionLink("Update", "GetEnvironment", "Environments", new { id = Model.Id }, new
       {
           data_ajax = "true",
           data_ajax_method = "GET",
           data_ajax_mode = "replace",
           data_ajax_update = "environment-container",
           @class = "btn btn-danger"
       }) 

控制:

public async Task<ActionResult> GetEnvironment(int? id)
{

        var environments = await _context.Environments.SingleOrDefaultAsync(m => m.Id == id);
        return PartialView("_Environment",environments);
} 

局部视图:

@model PowerPhysics.Models.Environments
this is a partial view

然后我尝试使用ViewComponents。当页面加载时,组件正常工作,但我不知道如何在之后仅刷新组件(例如通过按钮):

视图:

@Component.InvokeAsync("Environments", new { id = Model.Id }).Result

组件:

public class EnvironmentsViewComponent : ViewComponent
{
    public EnvironmentsViewComponent(PowerPhysics_DataContext context)
    {
        _context = context;
    }

    public async Task<IViewComponentResult> InvokeAsync(int? id)
    {
        var environments = await _context.Environments.SingleOrDefaultAsync(m => m.Id == id);

        return View(environments);
    }
}

我该如何在MVC6中使用PartialViews更新视图的部分内容?

使用JavaScript向您的操作发出Ajax调用,该操作返回部分视图。在Ajax调用的成功回调中,从结果中获取HTML并更新您的容器。 - Developer
2
是的,我可以使用JavaScript,但我想知道在MVC6和HTML5中是否有更好的方法。也许我的代码有问题。最重要的是,我想了解什么是最佳实践。 - user4019463
4个回答

7
您可以按照以下方式使用标签:
 <a data-ajax="true"
                       data-ajax-loading="#loading"
                       data-ajax-mode="replace"
                       data-ajax-update="#editBid"
                       href='@Url.Action("_EditBid", "Bids", new { bidId = Model.BidId, bidType = Model.BidTypeName })'
                       class="TopIcons">Link
                        </a>

请确保在您的_Layout.cshtml页面中,在body标签的末尾有以下脚本标记:
<script src="~/lib/jquery/jquery.unobtrusive-ajax/jquery.unobtrusive-ajax.js"></script>

为什么 data-ajax="true" 阻止文件获取?有人知道吗? 一旦移除,代码就可以正常工作... - malik masis

3
ViewComponent并不是ajax链接的替代品。它更像是Html.Action调用,用于在页面中包含子动作(例如:加载菜单栏)。这将在razor为视图执行页面时执行。
截至目前为止,aspnet core没有官方支持ajax action链接的替代方法。
但好消息是,我们可以用极少量的jQuery / javascript代码来实现ajax化。您可以使用现有的Anchor标记助手来完成此操作。
<a asp-action="GetEnvironment"  asp-route-id="@Model.Id" asp-controller="Environments" 
                                 data-target="environment-container" id="aUpdate">Update</a>
<div id="environment-container"></div>

在javascript代码中,只需监听链接点击事件,发起调用并更新DOM。
$(function(){

   $("#aUpdate").click(function(e){

     e.preventDefault();
     var _this=$(this);
     $.get(_this.attr("href"),function(res){
         $('#'+_this.data("target")).html(res);
     });

   });

});

由于您正在通过查询字符串传递参数,因此您也可以使用jQuery的 load 方法。

$(function(){

   $("#aUpdate").click(function(e){

     e.preventDefault();
     $('#' + $(this).data("target")).load($(this).attr("href"));

   });

});

谢谢,我试过了,但是当我点击链接时,它进入js函数,但没有调用控制器中的操作。$(this).data("target") 包含:"#environment-container",$(this).attr("href") 包含:"/Environments/GetEnvironment/3"。 - user4019463
打开你的浏览器控制台(网络和控制台),看看是否有任何JS错误或者它正在进行网络调用。你可以从网络调用中看到响应。 - Shyju

1
我为ASP.NET MVC Core的Anchor TagHelper添加了ajax选项。
你可以在github链接中看到完整的示例: https://github.com/NevitFeridi/AJAX-TagHelper-For-ASP.NET-Core-MVC 使用这个新的tagHelper后,你可以像下面展示的那样非常容易地在锚点中使用ajax选项:
     <a asp-action="create" asp-controller="sitemenu" asp-area="admin"
                        asp-ajax="true"
                        asp-ajax-method="get" 
                        asp-ajax-mode="replace"
                        asp-ajax-loading="ajaxloading"
                        asp-ajax-update="modalContent"
                        asp-ajax-onBegin="showModal()"
                        asp-ajax-onComplete=""
                        class="btn btn-success btn-icon-split">
                        <span class="icon text-white-50"><i class="fas fa-plus"></i></span>
                        <span class="text"> Add Menu </span>
  </a>

谢谢你的项目。我已经将它集成到我的项目中,现在它可以正常工作了。 - malik masis

0
请使用标签助手,并确保在您的视图文件夹中包括_ViewImport。
注意:如果有几个链接指向不同的页面以更新您的DIV,请确保使用document.getElementsByName.
示例 - Razor页面
<script type="text/javascript" language="javascript">
    $(function () {
        var myEl = document.getElementsByName('theName');
        $(myEl).click(function (e) {

            e.preventDefault();
            var _this = $(this);
            $.get(_this.attr("href"), function (res) {
                $('#' + _this.data("target")).html(res);
            });
        });
    });
</script>
<a asp-action="Index" asp-controller="Battle" data-target="divReplacable" name="theName" >Session</a>
<a asp-action="Index" asp-controller="Peace" data-target="divReplacable" name="theName" >Session</a>


<div id="divReplacable">
    Some Default Content
</div>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接