【问题标题】:JQuery .on not working when content is being called from Ajax当从 Ajax 调用内容时,JQuery .on 不起作用
【发布时间】:2017-11-19 20:58:27
【问题描述】:

我发现很多人都解决了一个问题,但似乎没有一个解决方案对我有用。也许这是我的方法。

我有一个编辑页面(用于Album),其中有一个foreach 插入一个Partial View。编辑页面旨在为该Album 显示Genres 的动态列表,它目前可以添加一个新的下拉菜单(部分视图),选择并保存(在控制器中)。

我可能想补充一点,这是使用 JQuery 3.x 的带有实体框架的 MVC

Edit.cshtml 查看(注意@foreach (var albumGenre in Model.AlbumGenres) 和后来的Ajax 链接@Ajax.ActionLink():

@model x.ViewModel.AlbumView
@using HtmlHelpers.BeginCollectionItem

@using (Html.BeginForm())
{
    @Html.AntiForgeryToken()

    <div class="form-horizontal">

        @* Removing a bunch of code *@

        <div class="form-group">
            @Html.LabelFor(model => model.AlbumGenres, htmlAttributes: new { @class = "control-label col-md-2" })
            <div class="col-md-10">
                <div>
                    <table id="genres" style="border: 0px solid black;">
                        <tr>
                            <td>&nbsp;</td>
                        </tr>

                        @foreach (var albumGenre in Model.AlbumGenres)
                        {
                            TempData["Genres"] = new SelectList(ViewBag.Genres, "Value", "Text", albumGenre.Genre.Oid);

                            //This is the PartialView
                            @Html.Partial("~/Views/Genres/_EditGenre.cshtml", albumGenre, ViewData)
                        }

                    </table>

                    <div class="form-group">
                        <div class="col-md-10" style="float: right;">

                            // This calls the Controller = 
                            // public ActionResult AddNewGenre(Guid id) { return PartialView("~/Views/Genres/_EditGenre.cshtml", new AlbumsGenres(id)); }
                            @Ajax.ActionLink(
                                "Add Genre to Album",
                                "AddNewGenre", 
                                null,
                                new { id = Model.Oid },
                                new AjaxOptions
                                {
                                    HttpMethod = "GET",
                                    InsertionMode = InsertionMode.InsertAfter,
                                    UpdateTargetId = "genres"
                                },
                                new { style = "btn btn-info" }
                            )
                        </div>
                    </div>

                </div>

            </div>
        </div>

        @* Save button *@
    </div>
}

@* Next line is commented out as I need to run this script inside the _CreateGenre.cshtml (show further down in this question) *@
@* Hoping to load the JavaScript here so that it only needs to run once (not foreach Genre in the Album *@
@*<script src="~/Scripts/ContentPub/AddGenre.js" type="text/javascript"></script>*@

@* *@

从那里我有_EditGenre.cshtml 视图:

@model ContentPub.Models.Music.AlbumsGenres

@{ 
    if (TempData["Genres"] == null)
    {
        TempData["Genres"] = new SelectList(ViewBag.Genres, "Value", "Text", null);
    }

    TempData["ShowDisplay"] = false;
    TempData["BlankValue"] = "Select a Genre";
}

@using (Html.BeginCollectionItem("AlbumGenres"))
{
    <tr>
        <td>
            <div id="GenreRow" class="form-group colorRow">
                <div class="col-md-7">
                    @Html.HiddenFor(model => model.Oid)
                    @Html.HiddenFor(model => model.Album.Oid)

                    @Html.DropDownListFor(model => model.Genre.Oid, TempData["Genres"] as SelectList, TempData["BlankValue"] as String, htmlAttributes: new { @class = "form-control genreDropDown" })
                    @Html.ValidationMessageFor(model => model.Genre.Oid, "", new { @class = "text-danger" })
                </div>

                <div id="genreDialog" class="genreDialog"></div>

                <div class="col-md-5">
                    <a class="button genreLink" href="@Url.Content("~/Genres/_Create")" id="genreAddLink_@Model.Oid">+</a>
                </div>
            </div>

        </td>
    </tr>
}

<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>


@* This needs to be active for the button to work, it looks like this: id="genreAddLink_@Model.Oid" *@
@* Also sad that it needs to be called for each Genre Partial View *@
<script src="~/Scripts/ContentPub/AddGenre.js" type="text/javascript"></script>

@* *@

下面是我的AddGenre.js 脚本:

首先是.dialog 部分:

$(document).ready(function () {

    $('#genreDialog').dialog({
        autoOpen: false,
        width: 600,
        height: 300,
        modal: true,
        title: 'Add Genre',

        buttons: {
            'Save': function () {
                // Removed for simplicity
            },

            'Cancel': function () {
                $(this).dialog('close');
            }
        }
    });

});

然后是 .on('click'... 部分(这是在将 Ajax 内容添加到页面时不会调用的部分):

//$(document).ready(function () { //Tried with and without this

    // This is the old code that didn't work
    // $('.genreLink').on('click', function () { 

    //This is the supposive solution
    $('#GenreRow').on('click', '.genreLink', function () { // Also tried 'body' where '#GenreRow' is

        console.log("Clicked");
        var select = $(this).parent().parent().find('select');

        $('#genreDialog')
            .data("select", select)
            .dialog('open');

        var createFormUrl = $(this).attr('href');

        $('#genreDialog').html('')

            .load(createFormUrl, function () {
                jQuery.validator.unobtrusive.parse('#createGenreForm');
            });

        return false;

    });

//});

简而言之,我可以打开此编辑页面,单击+ 以添加新的流派(在模态窗口中),通过 JavaScript 更新所有下拉菜单(并让适当的下拉菜单选择新选项),对此感到高兴。但是,我无法单击Add Genre to Album(Ajax 调用),然后单击新类型下拉菜单旁边的+,当我希望它打开模态窗口时它导航到_CreateGenre(JavaScript/jQuery 没有触发)。

$('#GenreRow').on('click', '.genreLink', function () { 没有被解雇,我不知道如何让它这样做。另一个例子,当通过 Ajax 从 Partial View 加载内容时,添加 console.log('JavaScript test'); 不会触发。

【问题讨论】:

  • “还尝试了 '#genreLink' 所在的 'body'” body 会去 #GenreRow 所在的地方,而不是 .genreLink 所在的地方
  • 是的,你说得对,我会更新,谢谢
  • .on 何时何地被调用?如果您在 ajax 完成之前调用该函数并将 HTML 添加到页面,它不会将自己分配给新的 HTML。

标签: javascript c# ajax asp.net-mvc jquery-3


【解决方案1】:

您的#GenreRow 正在由您的局部视图动态添加。当您运行 javascript 以将函数附加到 .genreLink 的点击事件时,您的 #GenreRow 可能在那时您的 DOM 上尚不存在,因此不会产生任何影响。当您的 DOM 准备就绪时,您似乎正在执行此操作(我假设这会在您的部分视图被触发/添加到 DOM 之前)。

试试:

$('body').on('click', '.genreLink', function () {
   ...
}

另一种选择是向您的 Add Genre div 添加一个类:

<div class="AddGenreSection" class="form-group">
   <div class="col-md-10" style="float: right;">
      @Ajax.ActionLink("Add Genre to Album", ...)
   </div>
</div>

而且由于这个 div 从一开始就存在(因为它是 Edit.cshtml 的一部分),您可以像这样将点击事件附加到该 div:

$('.AddGenreSection').on('click', '.genreLink', function () {
   ...
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-01
    • 2020-07-12
    • 2015-04-24
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 1970-01-01
    相关资源
    最近更新 更多