You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 5中ngx-bootstrap模态框如何处理含ESC键在内的所有关闭场景?

Got it, let's work through implementing all the close scenarios for your reusable modal—including the ESC key. Since your modal returns a Promise, we need to make sure every way the user closes it properly resolves/rejects that Promise and cleans up after itself to avoid memory leaks. Here's a complete implementation tailored to your existing code:

Full Modal Close Logic Implementation
createNewTimelineItemModal(): Promise<Object> {
  return new Promise((resolve, reject) => {
    const initialState = {
      title: 'Add',
      multipleChoice: 'Bid <i class="fa fa-telegram"></i>',
      choices: [
        'Bid <i class="fa fa-telegram"></i>',
        'D.C. <i class="fa fa-bandcamp"></i>',
        'Kick-off <i class="fa fa-grav"></i>'
      ]
    };

    // 1. Build modal DOM (adjust classes/structure to match your existing component)
    const modalOverlay = document.createElement('div');
    modalOverlay.className = 'modal-overlay'; // Assume this covers the full viewport
    const modalContent = document.createElement('div');
    modalContent.className = 'modal-content'; // Centered modal container

    // Populate modal with your timeline content
    modalContent.innerHTML = `
      <div class="modal-header">
        <h3>${initialState.title}</h3>
        <button class="modal-close-btn">&times;</button>
      </div>
      <div class="modal-body">
        <select class="timeline-choice">
          ${initialState.choices.map(choice => `<option>${choice}</option>`).join('')}
        </select>
        <!-- Add any other timeline form fields here -->
      </div>
      <div class="modal-footer">
        <button class="modal-cancel-btn">Cancel</button>
        <button class="modal-confirm-btn">Save</button>
      </div>
    `;

    modalOverlay.appendChild(modalContent);
    document.body.appendChild(modalOverlay);

    // 2. Core close handler with cleanup
    const closeModal = (isConfirmed = false, resultData = null) => {
      // Remove all event listeners to prevent memory leaks
      document.removeEventListener('keydown', handleEscPress);
      modalOverlay.removeEventListener('click', handleOverlayClick);
      closeBtn.removeEventListener('click', handleCloseClick);
      cancelBtn.removeEventListener('click', handleCancelClick);
      confirmBtn.removeEventListener('click', handleConfirmClick);
      
      // Remove modal from DOM
      document.body.removeChild(modalOverlay);
      
      // Resolve/reject Promise based on user action
      if (isConfirmed) {
        resolve(resultData); // Pass the final timeline data here
      } else {
        reject(new Error('Modal closed by user')); // Or resolve with null if you prefer
      }
    };

    // 3. Handle ESC key press
    const handleEscPress = (e) => {
      if (e.key === 'Escape') closeModal(false);
    };
    document.addEventListener('keydown', handleEscPress);

    // 4. Handle click outside modal content (overlay)
    const handleOverlayClick = (e) => {
      // Only close if click is directly on the overlay (not content inside)
      if (e.target === modalOverlay) closeModal(false);
    };
    modalOverlay.addEventListener('click', handleOverlayClick);

    // 5. Handle click on "X" close button
    const closeBtn = modalContent.querySelector('.modal-close-btn');
    const handleCloseClick = () => closeModal(false);
    closeBtn.addEventListener('click', handleCloseClick);

    // 6. Handle cancel button click
    const cancelBtn = modalContent.querySelector('.modal-cancel-btn');
    const handleCancelClick = () => closeModal(false);
    cancelBtn.addEventListener('click', handleCancelClick);

    // 7. Handle confirm/save button click (completes the action)
    const confirmBtn = modalContent.querySelector('.modal-confirm-btn');
    const handleConfirmClick = () => {
      // Collect your timeline item data here
      const selectedChoice = modalContent.querySelector('.timeline-choice').value;
      closeModal(true, { 
        choice: selectedChoice,
        // Add any other form data you need to return
      });
    };
    confirmBtn.addEventListener('click', handleConfirmClick);
  });
}

Key Details to Note

  • Promise Handling: Every close path calls closeModal() which either resolves (on successful save) or rejects (on cancellation) the Promise. Adjust this to resolve with null instead of rejecting if that fits your app's error handling pattern better.
  • Event Cleanup: We remove all event listeners before deleting the modal from the DOM—this is critical for reusable components to avoid lingering listeners that can cause bugs or memory leaks.
  • Overlay Click Guard: The overlay click handler checks if the target is the overlay itself, so clicking inside the modal content won't accidentally close it.
  • CSS Dependencies: Make sure your .modal-overlay and .modal-content classes have proper styling (e.g., overlay covers the viewport, content is centered, pointer events work as expected).

内容的提问来源于stack exchange,提问作者tatsu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:12:57