소스 검색

Allow referencing elements outside of x-init

Caleb Porzio 3 년 전
부모
커밋
c0045f0eeb
3개의 변경된 파일22개의 추가작업 그리고 3개의 파일을 삭제
  1. 2 2
      packages/alpinejs/src/directives/x-init.js
  2. 7 1
      packages/alpinejs/src/lifecycle.js
  3. 13 0
      tests/cypress/integration/magics/$refs.spec.js

+ 2 - 2
packages/alpinejs/src/directives/x-init.js

@@ -1,8 +1,8 @@
 import { directive, prefix } from "../directives";
-import { addRootSelector } from "../lifecycle";
+import { addInitSelector } from "../lifecycle";
 import { skipDuringClone } from "../clone";
 import { evaluate } from "../evaluator";
 
-addRootSelector(() => `[${prefix('init')}]`)
+addInitSelector(() => `[${prefix('init')}]`)
 
 directive('init', skipDuringClone((el, { expression }) => evaluate(el, expression, {}, false)))

+ 7 - 1
packages/alpinejs/src/lifecycle.js

@@ -22,7 +22,7 @@ export function start() {
 
     let outNestedComponents = el => ! closestRoot(el.parentNode || closestRoot(el))
 
-    Array.from(document.querySelectorAll(rootSelectors()))
+    Array.from(document.querySelectorAll(allSelectors()))
         .filter(outNestedComponents)
         .forEach(el => {
             initTree(el)
@@ -32,12 +32,18 @@ export function start() {
 }
 
 let rootSelectorCallbacks = []
+let initSelectorCallbacks = []
 
 export function rootSelectors() {
     return rootSelectorCallbacks.map(fn => fn())
 }
 
+export function allSelectors() {
+    return rootSelectorCallbacks.concat(initSelectorCallbacks).map(fn => fn())
+}
+
 export function addRootSelector(selectorCallback) { rootSelectorCallbacks.push(selectorCallback) }
+export function addInitSelector(selectorCallback) { initSelectorCallbacks.push(selectorCallback) }
 
 export function closestRoot(el) {
     if (rootSelectors().some(selector => el.matches(selector))) return el

+ 13 - 0
tests/cypress/integration/magics/$refs.spec.js

@@ -38,3 +38,16 @@ test('can reference elements from x-init',
         get('span').should(haveText('lob'))
     }
 )
+
+test('can reference elements outside of x-init',
+    html`
+        <div x-data x-ref="foo" data-foo="bar">
+            <div x-init="() => {}">
+                <span x-text="$refs.foo.dataset.foo"></span>
+            </div>
+        </div>
+    `,
+    ({ get }) => {
+        get('span').should(haveText('bar'))
+    }
+)