Преглед изворни кода

Allow passing parameters to Alpine.data

Caleb Porzio пре 4 година
родитељ
комит
93a80a4856

+ 14 - 2
packages/alpinejs/src/datas.js

@@ -5,6 +5,18 @@ export function data(name, callback) {
     datas[name] = callback
 }
 
-export function getNamedDataProvider(name) {
-    return datas[name]
+export function injectDataProviders(obj, context) {
+    Object.entries(datas).forEach(([name, callback]) => {
+        Object.defineProperty(obj, name, {
+            get() {
+                return (...args) => {
+                    return callback.bind(context)(...args)
+                }
+            },
+
+            enumerable: false,
+        })
+    })
+
+    return obj
 }

+ 7 - 11
packages/alpinejs/src/directives/x-data.js

@@ -1,10 +1,10 @@
 import { directive, prefix } from '../directives'
 import { initInterceptors } from '../interceptor'
-import { getNamedDataProvider } from '../datas'
+import { injectDataProviders } from '../datas'
 import { addRootSelector } from '../lifecycle'
 import { skipDuringClone } from '../clone'
 import { addScopeToNode } from '../scope'
-import { injectMagics } from '../magics'
+import { injectMagics, magic } from '../magics'
 import { reactive } from '../reactivity'
 import { evaluate } from '../evaluator'
 
@@ -13,17 +13,13 @@ addRootSelector(() => `[${prefix('data')}]`)
 directive('data', skipDuringClone((el, { expression }, { cleanup }) => {
     expression = expression === '' ? '{}' : expression
 
-    let dataProvider = getNamedDataProvider(expression)
+    let magicContext = {}
+    injectMagics(magicContext, el)
 
-    let data = {}
+    let dataProviderContext = {}
+    injectDataProviders(dataProviderContext, magicContext)
 
-    if (dataProvider) {
-        let magics = injectMagics({}, el)
-
-        data = dataProvider.bind(magics)()
-    } else {
-        data = evaluate(el, expression)
-    }
+    data = evaluate(el, expression, { scope: dataProviderContext })
 
     injectMagics(data, el)
 

+ 47 - 0
tests/cypress/integration/custom-data.spec.js

@@ -17,6 +17,53 @@ test('can register custom data providers',
     ({ get }) => get('span').should(haveText('bar'))
 )
 
+test.only('can accept initial params',
+    html`
+        <script>
+            document.addEventListener('alpine:init', () => {
+                Alpine.data('test', (first, second) => ({
+                    foo: first,
+                    bar: second,
+                }))
+            })
+        </script>
+
+        <div x-data="test('baz', 'bob')">
+            <h1 x-text="foo"></h1>
+            <h2 x-text="bar"></h2>
+        </div>
+    `,
+    ({ get }) => {
+        get('h1').should(haveText('baz'))
+        get('h2').should(haveText('bob'))
+    }
+)
+
+test.only('can spread together',
+    html`
+        <script>
+            document.addEventListener('alpine:init', () => {
+                Alpine.data('test', (first) => ({
+                    foo: first,
+                }))
+
+                Alpine.data('test2', (second) => ({
+                    bar: second,
+                }))
+            })
+        </script>
+
+        <div x-data="{ ...test('baz'), ...test2('bob') }">
+            <h1 x-text="foo"></h1>
+            <h2 x-text="bar"></h2>
+        </div>
+    `,
+    ({ get }) => {
+        get('h1').should(haveText('baz'))
+        get('h2').should(haveText('bob'))
+    }
+)
+
 test('init functions inside custom datas are called automatically',
     html`
         <script>