【问题标题】:Jquery click doesn't work twiceJquery单击不起作用两次
【发布时间】:2016-03-23 23:05:36
【问题描述】:

我正在尝试使用 ajax 编写 CRUD 操作。这里有一些代码: 这些是我的视图类:

//PhotoSummary
@model PhotoAlbum.WEB.Models.PhotoViewModel
<div class="well">
    <h3>
        <strong>@Model.Name</strong>
        <span class="pull-right label label-primary">@Model.AverageRaiting.ToString("# stars")</span>
    </h3>
    <span class="lead">@Model.Description</span>
    @Html.DialogFormLink("Update", Url.Action("UpdatePhoto", new {photoId = @Model.PhotoId}), "Update Photo", @Model.PhotoId.ToString(), Url.Action("Photo"))
</div>

//Main View
@model PhotoAlbum.WEB.Models.PhotoListViewModel
@{
    ViewBag.Title = "My Photos";
}
@foreach (var p in @Model.Photos)
{
    <div id=@p.PhotoId>
        @Html.Action("Photo", new {photo = p})
    </div>
}

剧本:

$('.dialogLink').on('click', function () {
    var element = $(this);       
    var dialogTitle = element.attr('data-dialog-title');
    var updateTargetId = '#' + element.attr('data-update-target-id');
    var updateUrl = element.attr('data-update-url');
    var dialogId = 'uniqueName-' + Math.floor(Math.random() * 1000)
    var dialogDiv = "<div id='" + dialogId + "'></div>";

    $(dialogDiv).load(this.href, function () {
        $(this).dialog({
            modal: true,
            resizable: false,
            title: dialogTitle,
            close: function () { $(this).empty(); },
            buttons: {
                "Save": function () {
                    // Manually submit the form                        
                    var form = $('form', this);
                    $(form).submit();
                },
                "Cancel": function () { $(this).dialog('close'); }
            }
        });

        $.validator.unobtrusive.parse(this);
        wireUpForm(this, updateTargetId, updateUrl);
    });
    return false;
});});


function wireUpForm(dialog, updateTargetId, updateUrl) {
    $('form', dialog).submit(function () {
        if (!$(this).valid())
            return false;
        $.ajax({
            url: this.action,
            type: this.method,
            data: $(this).serialize(),
            success: function (result) {

                if (result.success) {
                    $(dialog).dialog('close');
                    $(updateTargetId).load(updateUrl);
                } else {             
                    $(dialog).html(result);
                    $.validator.unobtrusive.parse(dialog);

                    wireUpForm(dialog, updateTargetId, updateUrl);
                }
            }
        });
        return false;
    });
}

这里是我的标签生成器:

    public static MvcHtmlString DialogFormLink(this HtmlHelper htmlHelper, string linkText, string dialogContentUrl,
         string dialogTitle, string updateTargetId, string updateUrl)
    {
        TagBuilder builder = new TagBuilder("a");
        builder.SetInnerText(linkText);
        builder.Attributes.Add("href", dialogContentUrl);
        builder.Attributes.Add("data-dialog-title", dialogTitle);
        builder.Attributes.Add("data-update-target-id", updateTargetId);
        builder.Attributes.Add("data-update-url", updateUrl);
        builder.AddCssClass("dialogLink");
        return new MvcHtmlString(builder.ToString());
    }

所以,如果在没有刷新调用页面的情况下调用了两次对话框,我会遇到重大问题: 它只是将我重定向到操作页面。 问题是如何在不重新加载页面的情况下更新@Html.Action? 谁能帮帮我?

【问题讨论】:

  • 您没有提供足够的信息来确定(您需要显示您生成的 html)。假设您的自定义@Html.DialogFormLink() 方法正在生成带有class=".dialogLink"&lt;a&gt; 元素,那么我猜它用包含@Html.DialogFormLink() 方法的新局部视图替换&lt;div id=@p.PhotoId&gt; 的内容。如果是这种情况,则需要使用事件委托,因此脚本需要为$(document).on('click', '.dialogLink', function() { ....
  • 虽然最好将document 替换为您首次呈现页面时存在的最近的祖先 - 例如&lt;div id="xxx"&gt;@foreach (var p in @Model.Photos) { ... }&lt;/div&gt; 然后$(#xxx).on(...
  • @StephenMuecke 非常感谢!使用“文档”可以正常工作!如果我用祖先替换它,我有 System.Web.HttpException:“执行处理程序'System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerAsyncWrapper'的子请求时出错。”
  • 如果是这样,你在某处犯了错误:)
  • @StephenMuecke 是的!我的错。弄错了。你能解释一下发生了什么吗?我不明白为什么我需要再添加一个 id 或使用#'document'?您也可以发布您的 cmets 作为答案!

标签: c# jquery ajax asp.net-mvc-5 crud


【解决方案1】:

您在主视图中的@foreach 循环正在为每个Photo 生成一个部分视图,这反过来又创建了一个与class="dialogLink" 的链接。

您的脚本处理这些链接的点击事件并将其替换为带有class="dialogLink" 的新链接。但是新链接没有.click() 处理程序,因此单击新(替换)链接不会激活您的脚本。

相反,您需要使用事件委托来处理使用.on() 方法动态生成的内容的事件(有关事件委托的更多信息,另请参阅here)。另请注意,您当前使用的$('.dialogLink').on('click', function () { 等效于$('.dialogLink').click(function () {,并且没有使用事件委托。它将处理程序附加到页面加载时存在于 DOM 中的元素,而不是将来可能添加的元素。

将您的 html 更改为

<div id="photos">
    @foreach (var p in @Model.Photos)
    {
        <div class="photo">@Html.Action("Photo", new { photo = p })</div>
    }
</div>

然后修改脚本为

$('#photos').on('click', '.dialogLink', function() { 
    ....
});

旁注:实际上不需要将id=@p.PhotoId 添加到包含div 的元素中,您可以按照上述使用&lt;div class="photo"&gt;,然后使用var updateTargetId = $(this).closest('.photo'); 引用它并删除builder.Attributes.Add("data-update-target-id", updateTargetId); DialogFormLink() 方法中的代码行

【讨论】:

    猜你喜欢
    • 2018-01-14
    • 2011-12-18
    • 2013-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-02
    • 2011-12-29
    相关资源
    最近更新 更多