diff --git a/core/modules/views/js/ajax_view.es6.js b/core/modules/views/js/ajax_view.es6.js
index 0c8535890b..f2fae7e0f5 100644
--- a/core/modules/views/js/ajax_view.es6.js
+++ b/core/modules/views/js/ajax_view.es6.js
@@ -21,6 +21,20 @@
       });
     }
   };
+  Drupal.behaviors.ViewsAjaxView.detach = (context, settings, trigger) => {
+    if (trigger === 'unload') {
+      if (drupalSettings && drupalSettings.views && drupalSettings.views.ajaxViews) {
+        const ajaxViews = drupalSettings.views.ajaxViews;
+        Object.keys(ajaxViews || {}).forEach((i) => {
+          const selector = `.js-view-dom-id-${ajaxViews[i].view_dom_id}`;
+          if ($(selector, context).length) {
+            delete Drupal.views.instances[i];
+            delete drupalSettings.views.ajaxViews[i];
+          }
+        });
+      }
+    }
+  };
 
   /**
    * @namespace
diff --git a/core/modules/views/js/ajax_view.js b/core/modules/views/js/ajax_view.js
index a10eb837eb..d58e81c825 100644
--- a/core/modules/views/js/ajax_view.js
+++ b/core/modules/views/js/ajax_view.js
@@ -15,6 +15,20 @@
       });
     }
   };
+  Drupal.behaviors.ViewsAjaxView.detach = function (context, settings, trigger) {
+    if (trigger === 'unload') {
+      if (drupalSettings && drupalSettings.views && drupalSettings.views.ajaxViews) {
+        var ajaxViews = drupalSettings.views.ajaxViews;
+        Object.keys(ajaxViews || {}).forEach(function (i) {
+          var selector = '.js-view-dom-id-' + ajaxViews[i].view_dom_id;
+          if ($(selector, context).length) {
+            delete Drupal.views.instances[i];
+            delete drupalSettings.views.ajaxViews[i];
+          }
+        });
+      }
+    }
+  };
 
   Drupal.views = {};
 
diff --git a/core/modules/views/tests/modules/views_test_modal/src/Controller/TestController.php b/core/modules/views/tests/modules/views_test_modal/src/Controller/TestController.php
new file mode 100644
index 0000000000..b89cf4081d
--- /dev/null
+++ b/core/modules/views/tests/modules/views_test_modal/src/Controller/TestController.php
@@ -0,0 +1,41 @@
+<?php
+
+namespace Drupal\views_test_modal\Controller;
+
+use Drupal\Component\Serialization\Json;
+use Drupal\Core\Controller\ControllerBase;
+use Drupal\Core\Url;
+
+class TestController extends ControllerBase {
+
+  /**
+   * Renders a link to open the /admin/content view in a modal dialog.
+   */
+  public function modal() {
+    $build = [];
+
+    $build['open_admin_content'] = [
+      '#type' => 'link',
+      '#title' => $this->t('Administer content'),
+      '#url' => Url::fromUserInput('/admin/content'),
+      '#attributes' => [
+        'class' => ['use-ajax'],
+        'data-dialog-type' => 'modal',
+        'data-dialog-options' => Json::encode([
+          'dialogClass' => 'views-test-modal',
+          'height' => '50%',
+          'width' => '50%',
+          'title' => $this->t('Administer content'),
+        ]),
+      ],
+      '#attached' => [
+        'library' => [
+          'core/drupal.dialog.ajax',
+        ],
+      ],
+    ];
+
+    return $build;
+  }
+
+}
diff --git a/core/modules/views/tests/modules/views_test_modal/views_test_modal.info.yml b/core/modules/views/tests/modules/views_test_modal/views_test_modal.info.yml
new file mode 100644
index 0000000000..59be6d4e51
--- /dev/null
+++ b/core/modules/views/tests/modules/views_test_modal/views_test_modal.info.yml
@@ -0,0 +1,9 @@
+name: 'Views Test Modal'
+type: module
+description: 'Provides a test page that renders a View in a modal.'
+package: Testing
+version: VERSION
+core: 8.x
+dependencies:
+  - drupal:node
+  - drupal:views
diff --git a/core/modules/views/tests/modules/views_test_modal/views_test_modal.routing.yml b/core/modules/views/tests/modules/views_test_modal/views_test_modal.routing.yml
new file mode 100644
index 0000000000..430bac18e5
--- /dev/null
+++ b/core/modules/views/tests/modules/views_test_modal/views_test_modal.routing.yml
@@ -0,0 +1,6 @@
+views_test_modal.modal:
+  path: '/views-test-modal/modal'
+  defaults:
+    _controller: '\Drupal\views_test_modal\Controller\TestController::modal'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/views/tests/src/FunctionalJavascript/ExposedFilterAJAXTest.php b/core/modules/views/tests/src/FunctionalJavascript/ExposedFilterAJAXTest.php
index 6aa52bcd12..db16071939 100644
--- a/core/modules/views/tests/src/FunctionalJavascript/ExposedFilterAJAXTest.php
+++ b/core/modules/views/tests/src/FunctionalJavascript/ExposedFilterAJAXTest.php
@@ -19,12 +19,14 @@ class ExposedFilterAJAXTest extends WebDriverTestBase {
   /**
    * {@inheritdoc}
    */
-  public static $modules = ['node', 'views'];
+  public static $modules = ['node', 'views', 'views_test_modal'];
 
   /**
-   * Tests if exposed filtering via AJAX works for the "Content" View.
+   * {@inheritdoc}
    */
-  public function testExposedFiltering() {
+  protected function setUp() {
+    parent::setUp();
+
     // Enable AJAX on the /admin/content View.
     \Drupal::configFactory()->getEditable('views.view.content')
       ->set('display.default.display_options.use_ajax', TRUE)
@@ -43,7 +45,12 @@ public function testExposedFiltering() {
       'edit any page content',
     ]);
     $this->drupalLogin($user);
+  }
 
+  /**
+   * Tests if exposed filtering via AJAX works for the "Content" View.
+   */
+  public function testExposedFiltering() {
     // Visit the View page.
     $this->drupalGet('admin/content');
 
@@ -91,4 +98,53 @@ public function testExposedFiltering() {
     $this->assertFalse($session->getPage()->hasButton('Reset'));
   }
 
+
+  /**
+   * Tests if exposed filtering via AJAX works in a modal.
+   */
+  public function testExposedFiltersInModal() {
+    $this->drupalGet('views-test-modal/modal');
+
+    $assert = $this->assertSession();
+
+    $assert->elementExists('named', ['link', 'Administer content'])->click();
+    $dialog = $assert->waitForElementVisible('css', '.views-test-modal');
+
+    $session = $this->getSession();
+    // Ensure that the Content we're testing for is present.
+    $html = $session->getPage()->getHtml();
+    $this->assertContains('Page One', $html);
+    $this->assertContains('Page Two', $html);
+
+    // Search for "Page One".
+    $session->getPage()->fillField('title', 'Page One');
+    $assert->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Filter');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Verify that only the "Page One" Node is present.
+    $html = $session->getPage()->getHtml();
+    $this->assertContains('Page One', $html);
+    $this->assertNotContains('Page Two', $html);
+
+    // Close and re-open the modal.
+    $assert->buttonExists('Close', $dialog)->press();
+    $assert->elementExists('named', ['link', 'Administer content'])->click();
+    $assert->waitForElementVisible('css', '.views-test-modal');
+
+    // Ensure that the Content we're testing for is present.
+    $html = $session->getPage()->getHtml();
+    $this->assertContains('Page One', $html);
+    $this->assertContains('Page Two', $html);
+
+    // Search for "Page One".
+    $session->getPage()->fillField('title', 'Page One');
+    $assert->elementExists('css', '.ui-dialog-buttonpane')->pressButton('Filter');
+    $this->assertSession()->assertWaitOnAjaxRequest();
+
+    // Verify that only the "Page One" Node is present.
+    $html = $session->getPage()->getHtml();
+    $this->assertContains('Page One', $html);
+    $this->assertNotContains('Page Two', $html);
+  }
+
 }
