首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >ASP.NET MVC核心-具有动态加载的PartialViews的JavaScript事件处理程序

ASP.NET MVC核心-具有动态加载的PartialViews的JavaScript事件处理程序
EN

Stack Overflow用户
提问于 2018-09-20 01:08:03
回答 1查看 1.2K关注 0票数 2

我在我的视图文件中有这个脚本,它的目的是填充相同视图的一部分,但只是其中的一小部分,这是一个包含Bootstrap面板类的HTML div:

代码语言:javascript
复制
<script type="text/javascript">
    function GetVehicles() {      
                     $.get('@Context.Request.Scheme://@hostname/@controller/GetVehicles', {id: @Model.Id}, function (response) {
                                            $("#tabOutVehicles").html(response);
                                        });
                                    }

function GetMedInfo() {
    $.get('@Context.Request.Scheme://@hostname/@controller/GetMedInfo', {id: @Model.Id}, function (response) {
           $("#tabOutMedInfo").html(response);

    });
}
</script>

我的完整视图,它将显示由上述脚本生成的输出:

代码语言:javascript
复制
    @{
        Layout = "~/Views/Shared/_Layout.cshtml";
    }
    <script src="~/js/site.js"></script>

        <div class="panel panel-primary">
                                <div class="panel-heading">
                                    <a href="#collapseVehicles" class="btn student-dash-btn" onclick="GetVehicles()" data-toggle="collapse">Vehicles</a>
                                </div>

                                <div id="collapseVehicles" class="panel-collapse collapse">
                                    <div id="tabOutVehicles">
                                    </div>
                                </div>
                            </div>

                            <div class="panel panel-primary">
                                <div class="panel-heading">
                                    <a href="#collapseMedInfo" class="btn student-dash-btn" onclick="GetMedInfo()" data-toggle="collapse"><strong style="color:white">Medical Info</strong></a>
                                </div>

                                <div id="collapseMedInfo" class="panel-collapse collapse">
                                    <div id="tabOutMedInfo">
                                    </div>
                                </div>
                            </div>

<script type="text/javascript">
        function GetVehicles() {      
                         $.get('@Context.Request.Scheme://@hostname/@controller/GetVehicles', {id: @Model.Id}, function (response) {
                                                $("#tabOutVehicles").html(response);
                                            });
                                        }

    function GetMedInfo() {
        $.get('@Context.Request.Scheme://@hostname/@controller/GetMedInfo', {id: @Model.Id}, function (response) {
               $("#tabOutMedInfo").html(response);

        });
    }
    </script>

通过单击Bootstrap面板div中的超链接,jQuery方法将命中我的控制器操作,返回响应,然后将响应放入适用的div (#tabOutMedInfo / #tabOutVehicles)。这两个操作都会返回部分视图。下面是我的局部视图的样子,除了模型属性不同之外,两者看起来都是一样的:

代码语言:javascript
复制
@model MyViewModel
    <div class="panel-body">
        <a data-url="@Url.Action("EditMedInfo", "Controller", new { id = Model.Id })" data-toggle="ajax-modal" data-target="#EditMedInfo" class="btn btn-default">Edit</a>

        <div class="form-horizontal">
            <div class="">
                <div class="form-group">
                    <div class="col-md-5 col-sm-5 col-xs-5"><label asp-for="Variable" class="control-label"></label></div>
                    <div class="col-md-7 col-sm-7 col-xs-7">
                        @Html.DisplayFor(item => item.Variable)
                    </div>
                </div>
            </div>
        </div>
    </div>

当单击上面的超链接时,它应该执行加载模式进行编辑的JavaScript代码,但这并没有发生,相反,它不会打开模式。JavaScript代码位于我的site.js文件中,该文件正在我的主视图中导入。

我尝试过的东西:

我将脚本导入标记移动到我的部分视图中,然后将其从我的视图中删除,然后它会导致JavaScript代码运行并显示我的模式,但这个解决方案只工作了一段时间。

新问题:

然后,一个新的问题开始出现,如果加载了第一个部分视图,而您在不关闭网页的情况下加载了第二个部分视图,则会导致site.js被加载到视图中两次,第一个部分视图加载一次,第二个部分视图加载第二次。site.js加载了两次,不知何故导致我的post操作被命中两次,导致一个post操作插入两次数据。

然后,我决定将site.js移动到我的_Layout.cshtml (理想情况下是这样),并再次尝试,这种方法使部分视图呈现为正常视图,但再次,当单击部分视图中的超链接时,模态没有显示。

我的理论:

据我所知,当jQuery get方法加载部分视图时,它会阻止部分视图看到site.js,即使它是由我的_Layout.cshtml加载的。

我最好不想改变的是:

我不想摆脱我的小get操作,我这样构建它是为了让我的用户尽可能多地留在一个页面上,并且单独调用get操作可以减少他们的数据使用量。

我是否正确加载了site.js?为什么我的局部视图看不到site.js?

编辑:

这是我的_Layout.cshtml

代码语言:javascript
复制
<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
    <environment names="Development">
        @*Other scripts omitted *@
        <script src="~/js/site.js" asp-append-version="true" defer></script>
    </environment>

    <environment names="Staging,Production">
        @*Other scripts omitted *@
        <script src="~/js/site.js" asp-append-version="true" defer></script>
    </environment>
</head>
<body>
    <div id="modal-placeholder"></div>
    @RenderBody()
    @RenderSection("scripts", required: false)
</body>
</html>

下面是位于site.js内部的JavaScript代码

代码语言:javascript
复制
$(function () {
    var placeholderElement = $('#modal-placeholder');
    var redirectUrl = "";

    $('a[data-toggle="ajax-modal"]').click(function (event) {
        var url = $(this).data('url');
        redirectUrl = window.location.href;

        $.get(url).done(function (data) {
            placeholderElement.html(data);
            placeholderElement.find('.modal').modal('show');
        });
    });

    placeholderElement.on('click', '[data-save="modal"]', function (event) {
        event.preventDefault();

        var form = $(this).parents('.modal').find('form');
        var actionUrl = form.attr('action');
        var dataToSend = form.serialize();

        $.post(actionUrl, dataToSend).done(function (data) {
            var newBody = $('.modal-body', data);
            placeholderElement.find('.modal-body').replaceWith(newBody);
            var isValid = newBody.find('[name="IsValid"]').val() == 'True';
            if (isValid) {
               placeholderElement.find('.modal').modal('hide');
               window.location.assign(redirectUrl);
               }
            }
        });
    });
});

类似于上面编写的用于处理模态的服务器端验证的JavaScript,请参阅这里的精彩文章:https://softdevpractice.com/blog/asp-net-core-mvc-ajax-modals/

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-09-20 02:23:03

当您将面板的HTML粘贴到从ajax调用返回的页面中时,它会破坏所有现有的事件处理程序。因此,您需要重新绑定处理程序锚元素。我会将您的事件处理程序包装在一个函数中,并在初始页面加载和ajax成功处理程序中调用该函数(在粘贴HTML之后)。假设您使用的是jQuery,它将如下所示:

代码语言:javascript
复制
function bindAjaxModalButtons() {
    $('[data-toggle="ajax-modal"]').click(function() {
        // ... your event handler code here
    });
}
$(function() {
    bindAjaxModalButtons(); // attaches event handlers on initial page load
});

然后更改ajax函数,如下所示:

代码语言:javascript
复制
function GetMedInfo() {
    $.get('@Context.Request.Scheme://@hostname/@controller/GetMedInfo', {id: @Model.Id}, function (response) {
        $("#tabOutMedInfo").html(response);
        bindAjaxModalButtons(); // <-- this will attach the event handler to the new buttons    
    });
}

编辑:现在我可以看到你的JS文件了,下面是它应该是什么样子:

代码语言:javascript
复制
$(function () {
    var placeholderElement = $('#modal-placeholder');
    var redirectUrl = "";

    bindAjaxModalButtons();

    placeholderElement.on('click', '[data-save="modal"]', function (event) {
        event.preventDefault();

        var form = $(this).parents('.modal').find('form');
        var actionUrl = form.attr('action');
        var dataToSend = form.serialize();

        $.post(actionUrl, dataToSend).done(function (data) {
            var newBody = $('.modal-body', data);
            placeholderElement.find('.modal-body').replaceWith(newBody);
            var isValid = newBody.find('[name="IsValid"]').val() == 'True';
            if (isValid) {
               placeholderElement.find('.modal').modal('hide');
               window.location.assign(redirectUrl);
               }
            }
        });
    });
});

function bindAjaxModalButtons() {
    var btns = $('a[data-toggle="ajax-modal"]');
    btns.unbind(); // <-- so that existing buttons don't get double-bound
    btns.click(function (event) {
        var url = $(this).data('url');
        redirectUrl = window.location.href;
        var placeholderElement = $('#modal-placeholder');
        $.get(url).done(function (data) {
            placeholderElement.html(data);
            placeholderElement.find('.modal').modal('show');
        });
    });
}
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52411003

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档