Jquery click не работает дважды

Я пытаюсь писать операции CRUD, используя ajax. Вот некоторый код: Это мои классы View:

//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;
    });
}

И вот мой Tag Builder:

    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 без перезагрузки страницы? Кто-нибудь может мне помочь?

1 ответ

Решение

Ваш @foreach цикл в главном представлении генерирует частичное представление для каждого Photo который в свою очередь создает ссылку с class="dialogLink",

Ваш скрипт обрабатывает событие click этих ссылок и заменяет его новой ссылкой class="dialogLink", Но новая ссылка не имеет .click() обработчик, поэтому нажатие на новую (замену) ссылку не активирует ваш скрипт.

Вместо этого вам нужно использовать делегирование событий для обработки событий для динамически генерируемого контента с использованием метода.on() (см. Также здесь для получения дополнительной информации о делегировании событий). Обратите внимание, что ваше текущее использование $('.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 элемент, и вы могли бы использовать <div class="photo"> как указано выше, а затем сослаться на него с помощью var updateTargetId = $(this).closest('.photo'); и удалите builder.Attributes.Add("data-update-target-id", updateTargetId); строка кода из вашего DialogFormLink() метод

Другие вопросы по тегам