jQuery дважды вызывал метод в контроллере (MVC)

#javascript #jquery #asp.net-mvc #asp.net-mvc-4

#javascript #jquery #asp.net-mvc #asp.net-mvc-4

Вопрос:

У меня будет этот код в index.cshtml

 <a href='@Url.Action("Create", "ShippingMethods")' data-toggle="modal" data-target=".modal" data-wrap="modal-lg"><i class="fa fa-edit fa-fw"></i> Edit</a>

<div class="modal fade" tabindex="-1" role="dialog" aria-labelledby="Modal">
    <div class="modal-dialog">
        <div class="modal-content">
            <!--Content Inside Here-->
        </div><!-- /.modal-content -->
    </div><!-- /.modal-dialog -->
</div>
  

И мой JQUERY:

 'use strict';

(function ($) {
     /* Ajax Form Submit for Modal */
    var ajaxFormSubmit = function () {

        var $form = $(this);

        $.ajax({
            url: $form.attr('action'),
            type: $form.attr('method'),
            data: $form.serialize(),
            beforeSend: function () {
                $('.spinner').addClass('fa fa-spinner fa-pulse fa-2x fa-fw');
            }
        })
        .done(function (data) {
            var $target = $($form.attr('data-target'));

            if (data.status == true) {
                $('.modal').modal('hide');
                location.reload();
            } else {
                $target.replaceWith(data);
            }
        });

        return false;
    }

    /* Empty Modal Content on Hide */
    $('.modal').on('hide.bs.modal', function (e) {
        $('.modal-content').empty();
        $('.modal-dialog').removeClass('modal-lg modal-sm');
    });

    $('.ShippingMethods')
        .on('click', 'a[data-toggle="modal"]', function () { // show modal
            $('.modal-dialog').addClass($(this).attr('data-wrap'));
            $('.modal-content').load($(this).attr('href'));
        })

        .on('submit', '.ajaxForm', ajaxFormSubmit); // modal ajax form submit

})(jQuery);
  

Мне было интересно, почему метод в контроллере вызывается дважды. Когда на самом деле я щелкнул по нему только один раз. Эта функция вызывалась дважды каждый раз, когда я нажимал на кнопку.

  public ActionResult Create()
        {
            var whs = new PluginManager().GetAllData();
            ViewBag.PluginId = new SelectList(whs, "PluginId", "Description");
            return View();
        }
  

У кого-нибудь есть идеи, почему он ведет себя странно? Я не могу понять, в чем здесь проблема? Заранее спасибо за помощь и советы 🙂

Ответ №1:

Вы не препятствуете поведению ссылки по умолчанию. У вас есть прослушиватель onclick, который выполняет вызов с использованием jQuery load , но после выполнения прослушивателя click ссылка перейдет к своему поведению по умолчанию, которое заключается в переходе по ссылке в href , и это ваш второй вызов.

Примите событие в качестве параметра для вашего слушателя и вызовите preventDefault его, чтобы остановить переход вашего браузера по ссылке.

 .on('click', 'a[data-toggle="modal"]', function (e) {
        e.preventDefault();
        $('.modal-dialog').addClass($(this).attr('data-wrap'));
        $('.modal-content').load($(this).attr('href'));
    })
  


Обновить:
Я понимаю, что собственный прослушиватель Bootstrap to data-toggle="modal" предотвратит действие по умолчанию для вас, поэтому нет необходимости делать это, как было предложено в моем первоначальном ответе.

Однако здесь вы видите, что Bootstrap автоматически интерпретирует значение в href качестве remote опции и также загружает содержимое для вас.

Обратите внимание, что remote он устарел в 3.3 и удален в Bootstrap 4. Если вы полагаетесь на этот метод, обратите внимание, что он перестанет работать, если вы обновите Bootstrap до более новой версии.

Я бы посоветовал вручную контролировать, когда, где и как загружается ваш контент. Сохраняйте свой $('.modal-content').load вызов там, но поскольку Bootstrap перехвачен href , вам нужно будет использовать что-то еще, например data-href .

Также: я отмечаю, что вы используете attr('data-...') для доступа к атрибутам данных. Обратите внимание, что jQuery также предоставляет их через data('...') :

 <a data-href="@Url.Action("Create", "ShippingMethods")"
  data-toggle="modal" 
  data-target=".modal" 
  data-wrap="modal-lg"><i class="fa fa-edit fa-fw"></i> Edit</a>

.on('click', 'a[data-toggle="modal"]', function () {
    $('.modal-dialog').addClass($(this).data('wrap'));
    $('.modal-content').load($(this).data('href'));
})
  

Комментарии:

1. Я вызвал preventDefault, но все равно дважды вызывал метод. Тот же результат.

2. @Jen143: Какие-либо ошибки в консоли? Выполните console.log внутри прослушивателя щелчков, чтобы определить, вызывается ли фактический прослушиватель дважды. Прокомментируйте вызов load — вы вдруг не видите никаких вызовов вообще или один, который должен поступать откуда-то еще?

3. Вау. Спасибо. Я закомментировал вызов load, и теперь он работает нормально. Он вызывается только один раз.

4. @Jen143: Эй, подожди, это была просто отладка. Разве вы не пытались загрузить содержимое при этом вызове? Кажется, что теперь у вас остался только один вызов, но из неизвестного источника. Вы не хотите оставлять все как есть, вы захотите знать, как, когда и почему вызывается ваше действие.

5. @Jen143: Я понял, что происходит с вашим кодом. Пожалуйста, посмотрите мой обновленный ответ.