防止 Bootstrap 模式中的多个事件处理

问题描述 投票:0回答:1

我有一个用于多个操作的引导模式,例如“添加用户”或“编辑用户”。每次我单击按钮时,它都会为我打开模式,我可以填写字段并提交。 但是,如果我单击第一个按钮,然后单击第二个按钮,然后再次单击第一个按钮,它会连续向我发送 3 次帖子。所以它每次都会为我创建一个新的事件侦听器。

如果我删除resetModal()函数中的事件监听器,那么它每次只向我发送一次POST,但第二次单击时按钮不会继续,并且console.log(state, 'state')仍为空。如果我给 AddEventListener 提供“once: true”,则行为完全相同。 所以我只能有一种行为。按钮要么在每次点击和数据状态等传递时起作用,要么每次提交只向我发送一个 POST。 我怎样才能让这两件事都起作用?

我有一个非常简化的 JSFiddle 可以尝试:https://jsfiddle.net/dvkyjtbz/1/

const exampleModal = document.querySelector('#exampleModal');
let isEventListenerAttached = false;

function resetModal(event) {
  const modalForm = event.currentTarget.querySelector('form');

  if (modalForm) {
    modalForm.reset();
  }
  
  // Remove to run RemoveEventListener
  // exampleModal.removeEventListener('show.bs.modal', handleUserModal);
}

function saveUserData(user, state) {
  const {
    title,
    body,
    userId,
  } = user;
  const url = (userId) ? `/${userId}` : '';
  const modal = bootstrap.Modal.getInstance(exampleModal);

  axios({
      method: (userId) ? 'put' : 'post',
      url: `https://jsonplaceholder.typicode.com/posts${url}`,
      data: {
        title: title,
        body: body,
        userId: userId,
      },
    })
    .then(response => {
      console.log('Success!')
      modal.hide();
    })
    .catch((err) => {
      console.log(err);
    });
}

function handleSubmit(event, modal, state, userID) {
  event.preventDefault();

  const modalTitle = modal.querySelector('.modal-body #title');
  const modalBody = modal.querySelector('.modal-body #body');

  saveUserData({
    title: modalTitle.value,
    body: modalBody.value,
    userId: (state === 'newUser') ? '' : userID,
  }, state);
}

function handleUserModal(event) {
  if (isEventListenerAttached) {
    return;
  }

  const button = event.relatedTarget;
  const state = button.getAttribute('data-state') || 'newUser';
  const userID = button.getAttribute('data-uid');
  const modal = event.currentTarget;
  const saveUserButton = modal.querySelector('[form-submit="useradministration-save-user"]');
  const title = (state === 'newUser') ? 'Add New User' : 'Edit User';
  const modalTitle = modal.querySelector('.modal-title');
  
  if (modalTitle) {
    modalTitle.textContent = title;
  }
  
  console.log(state, 'state')

  saveUserButton.addEventListener('click', (event) => {
    handleSubmit(event, modal, state, userID);
  });
}

exampleModal.addEventListener('show.bs.modal', handleUserModal);
exampleModal.addEventListener('hidden.bs.modal', resetModal);
javascript twitter-bootstrap event-handling modal-dialog bootstrap-modal
1个回答
0
投票

您面临的问题与打开和关闭模式时多次添加事件侦听器有关。您可以跟踪事件监听器是否已添加。

const exampleModal = document.querySelector('#exampleModal');
let isEventListenerAttached = false;

function resetModal(event) {
  const modalForm = event.currentTarget.querySelector('form');

  if (modalForm) {
    modalForm.reset();
  }
}

function saveUserData(user, state) {
  // ...
}

function handleSubmit(event, modal, state, userID) {
  event.preventDefault();

  const modalTitle = modal.querySelector('.modal-body #title');
  const modalBody = modal.querySelector('.modal-body #body');

  saveUserData({
    title: modalTitle.value,
    body: modalBody.value,
    userId: (state === 'newUser') ? '' : userID,
  }, state);
}

function handleUserModal(event) {
  if (isEventListenerAttached) {
    return;
  }

  const button = event.relatedTarget;
  const state = button.getAttribute('data-state') || 'newUser';
  const userID = button.getAttribute('data-uid');
  const modal = event.currentTarget;
  const saveUserButton = modal.querySelector('[form-submit="useradministration-save-user"]');
  const title = (state === 'newUser') ? 'Add New User' : 'Edit User';
  const modalTitle = modal.querySelector('.modal-title');

  if (modalTitle) {
    modalTitle.textContent = title;
  }

  saveUserButton.addEventListener('click', (event) => {
    handleSubmit(event, modal, state, userID);
  });

  isEventListenerAttached = true; // Set to true after adding the event listener
}

function removeEventListener() {
  const saveUserButton = exampleModal.querySelector('[form-submit="useradministration-save-user"]');
  saveUserButton.removeEventListener('click', (event) => {
    handleSubmit(event, exampleModal, 'newUser', null);
  });
}

exampleModal.addEventListener('show.bs.modal', handleUserModal);
exampleModal.addEventListener('hidden.bs.modal', resetModal);
exampleModal.addEventListener('hide.bs.modal', removeEventListener);
© www.soinside.com 2019 - 2024. All rights reserved.