mirror of
https://github.com/sveltejs/svelte.git
synced 2024-12-01 17:30:59 +01:00
client-side store subscriptions
This commit is contained in:
parent
2705532cb0
commit
f80ace5fd6
@ -184,15 +184,23 @@ export default function dom(
|
||||
const debugName = `<${generator.customElement ? generator.tag : name}>`;
|
||||
|
||||
// generate initial state object
|
||||
const globals = Array.from(generator.expectedProperties).filter(prop => globalWhitelist.has(prop));
|
||||
const expectedProperties = Array.from(generator.expectedProperties);
|
||||
const globals = expectedProperties.filter(prop => globalWhitelist.has(prop));
|
||||
const storeProps = options.store ? expectedProperties.filter(prop => prop[0] === '$') : [];
|
||||
|
||||
const initialState = [];
|
||||
|
||||
if (globals.length > 0) {
|
||||
initialState.push(`{ ${globals.map(prop => `${prop} : ${prop}`).join(', ')} }`);
|
||||
}
|
||||
|
||||
if (storeProps.length > 0) {
|
||||
initialState.push(`this.store._init([${storeProps.map(prop => `"${prop.slice(1)}"`)}])`);
|
||||
}
|
||||
|
||||
if (templateProperties.data) {
|
||||
initialState.push(`%data()`);
|
||||
} else if (globals.length === 0) {
|
||||
} else if (globals.length === 0 && storeProps.length === 0) {
|
||||
initialState.push('{}');
|
||||
}
|
||||
|
||||
@ -205,6 +213,7 @@ export default function dom(
|
||||
@init(this, options);
|
||||
${generator.usesRefs && `this.refs = {};`}
|
||||
this._state = @assign(${initialState.join(', ')});
|
||||
${storeProps.length > 0 && `this.store._add(this, [${storeProps.map(prop => `"${prop.slice(1)}"`)}]);`}
|
||||
${generator.metaBindings}
|
||||
${computations.length && `this._recompute({ ${Array.from(computationDeps).map(dep => `${dep}: 1`).join(', ')} }, this._state);`}
|
||||
${options.dev &&
|
||||
@ -215,7 +224,11 @@ export default function dom(
|
||||
${generator.bindingGroups.length &&
|
||||
`this._bindingGroups = [${Array(generator.bindingGroups.length).fill('[]').join(', ')}];`}
|
||||
|
||||
${templateProperties.ondestroy && `this._handlers.destroy = [%ondestroy]`}
|
||||
${(templateProperties.ondestroy || storeProps.length) && (
|
||||
`this._handlers.destroy = [${
|
||||
[templateProperties.ondestroy && `%ondestroy`, storeProps.length && `@removeFromStore`].filter(Boolean).join(', ')
|
||||
}]`
|
||||
)}
|
||||
|
||||
${generator.slots.size && `this._slotted = options.slots || {};`}
|
||||
|
||||
|
@ -56,6 +56,7 @@ export interface CompileOptions {
|
||||
legacy?: boolean;
|
||||
customElement?: CustomElementOptions | true;
|
||||
css?: boolean;
|
||||
store?: boolean;
|
||||
|
||||
onerror?: (error: Error) => void;
|
||||
onwarn?: (warning: Warning) => void;
|
||||
|
@ -65,12 +65,13 @@ export function get(key) {
|
||||
}
|
||||
|
||||
export function init(component, options) {
|
||||
component.options = options;
|
||||
|
||||
component._observers = { pre: blankObject(), post: blankObject() };
|
||||
component._handlers = blankObject();
|
||||
component._root = options._root || component;
|
||||
component._bind = options._bind;
|
||||
|
||||
component.options = options;
|
||||
component.store = component._root.options.store;
|
||||
}
|
||||
|
||||
export function observe(key, callback, options) {
|
||||
@ -187,6 +188,10 @@ export function _unmount() {
|
||||
this._fragment.u();
|
||||
}
|
||||
|
||||
export function removeFromStore() {
|
||||
this.store._remove(this);
|
||||
}
|
||||
|
||||
export var proto = {
|
||||
destroy: destroy,
|
||||
get: get,
|
||||
|
@ -63,6 +63,7 @@ describe("runtime", () => {
|
||||
compileOptions.shared = shared;
|
||||
compileOptions.hydratable = hydrate;
|
||||
compileOptions.dev = config.dev;
|
||||
compileOptions.store = !!config.store;
|
||||
|
||||
// check that no ES2015+ syntax slipped in
|
||||
if (!config.allowES2015) {
|
||||
@ -88,7 +89,7 @@ describe("runtime", () => {
|
||||
}
|
||||
} catch (err) {
|
||||
failed.add(dir);
|
||||
showOutput(cwd, { shared }, svelte); // eslint-disable-line no-console
|
||||
showOutput(cwd, { shared, store: !!compileOptions.store }, svelte); // eslint-disable-line no-console
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
@ -134,7 +135,7 @@ describe("runtime", () => {
|
||||
try {
|
||||
SvelteComponent = require(`./samples/${dir}/main.html`);
|
||||
} catch (err) {
|
||||
showOutput(cwd, { shared, hydratable: hydrate }, svelte); // eslint-disable-line no-console
|
||||
showOutput(cwd, { shared, hydratable: hydrate, store: !!compileOptions.store }, svelte); // eslint-disable-line no-console
|
||||
throw err;
|
||||
}
|
||||
|
||||
@ -154,7 +155,8 @@ describe("runtime", () => {
|
||||
const options = Object.assign({}, {
|
||||
target,
|
||||
hydrate,
|
||||
data: config.data
|
||||
data: config.data,
|
||||
store: config.store
|
||||
}, config.options || {});
|
||||
|
||||
const component = new SvelteComponent(options);
|
||||
@ -188,12 +190,12 @@ describe("runtime", () => {
|
||||
config.error(assert, err);
|
||||
} else {
|
||||
failed.add(dir);
|
||||
showOutput(cwd, { shared, hydratable: hydrate }, svelte); // eslint-disable-line no-console
|
||||
showOutput(cwd, { shared, hydratable: hydrate, store: !!compileOptions.store }, svelte); // eslint-disable-line no-console
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
if (config.show) showOutput(cwd, { shared, hydratable: hydrate }, svelte);
|
||||
if (config.show) showOutput(cwd, { shared, hydratable: hydrate, store: !!compileOptions.store }, svelte);
|
||||
});
|
||||
}
|
||||
|
||||
|
19
test/runtime/samples/store/_config.js
Normal file
19
test/runtime/samples/store/_config.js
Normal file
@ -0,0 +1,19 @@
|
||||
import Store from '../../../../store.js';
|
||||
|
||||
const store = new Store({
|
||||
name: 'world'
|
||||
});
|
||||
|
||||
export default {
|
||||
solo: true,
|
||||
|
||||
store,
|
||||
|
||||
html: `<h1>Hello world!</h1>`,
|
||||
|
||||
test(assert, component, target) {
|
||||
store.set({ name: 'everybody' });
|
||||
|
||||
assert.htmlEqual(target.innerHTML, `<h1>Hello everybody!</h1>`);
|
||||
}
|
||||
};
|
1
test/runtime/samples/store/main.html
Normal file
1
test/runtime/samples/store/main.html
Normal file
@ -0,0 +1 @@
|
||||
<h1>Hello {{$name}}!</h1>
|
Loading…
Reference in New Issue
Block a user