ソースを参照

Fix directive handler flushing order (#1901)

* Fix directive handler flushing order

* wip
Caleb Porzio 3 年 前
コミット
20c4fa0ac2

+ 1 - 1
index.html

@@ -15,4 +15,4 @@
             Content...
         </span>
     </div>
-</html>
+</html>

+ 12 - 3
packages/alpinejs/src/directives.js

@@ -34,13 +34,22 @@ export function directives(el, attributes, originalAttributeOverride) {
 }
 
 let isDeferringHandlers = false
-let directiveHandlerStack = []
+let directiveHandlerStacks = new Map
+let currentHandlerStackKey = Symbol()
 
 export function deferHandlingDirectives(callback) {
     isDeferringHandlers = true
 
+    let key = Symbol()
+
+    currentHandlerStackKey = key
+
+    directiveHandlerStacks.set(key, [])
+
     let flushHandlers = () => {
-        while (directiveHandlerStack.length) directiveHandlerStack.shift()()
+        while (directiveHandlerStacks.get(key).length) directiveHandlerStacks.get(key).shift()()
+
+        directiveHandlerStacks.delete(key)
     }
 
     let stopDeferring = () => { isDeferringHandlers = false; flushHandlers() }
@@ -82,7 +91,7 @@ export function getDirectiveHandler(el, directive) {
 
         handler = handler.bind(handler, el, directive, utilities)
 
-        isDeferringHandlers ? directiveHandlerStack.push(handler) : handler()
+        isDeferringHandlers ? directiveHandlerStacks.get(currentHandlerStackKey).push(handler) : handler()
     }
 
     fullHandler.runCleanups = doCleanup

+ 14 - 0
tests/cypress/integration/directives/x-html.spec.js

@@ -33,5 +33,19 @@ test('x-html allows alpine code within',
     ({ get }) => {
         get('h1').should(haveText('baz'))
     }
+)
+
+test.only('x-html runs even after x-if or x-for',
+    html`
+        <div x-data="{ html: '<span x-text=&quot;foo&quot;></span>', foo: 'bar' }">
+            <template x-if="true">
+                <h1>yoyoyo</h1>
+            </template>
 
+            <div x-html="html"></div>
+        </div>
+    `,
+    ({ get }) => {
+        get('span').should(haveText('bar'))
+    }
 )