allow passing in context in constructor (#6032)

Co-authored-by: Conduitry <git@chor.date>
pull/6157/head
Tan Li Hau 4 years ago committed by GitHub
parent bcf2313a34
commit 6c5257beb2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,5 +1,9 @@
# Svelte changelog # Svelte changelog
## Unreleased
* Allow root-level context to be passed to the component constructor ([#6032](https://github.com/sveltejs/svelte/pull/6032))
## 3.36.0 ## 3.36.0
* Add `this: void` typing to store functions ([#6094](https://github.com/sveltejs/svelte/pull/6094)) * Add `this: void` typing to store functions ([#6094](https://github.com/sveltejs/svelte/pull/6094))

@ -904,6 +904,7 @@ The following initialisation options can be provided:
| `target` | **none** | An `HTMLElement` to render to. This option is required | `target` | **none** | An `HTMLElement` to render to. This option is required
| `anchor` | `null` | A child of `target` to render the component immediately before | `anchor` | `null` | A child of `target` to render the component immediately before
| `props` | `{}` | An object of properties to supply to the component | `props` | `{}` | An object of properties to supply to the component
| `context` | `new Map()` | A `Map` of root-level context key-value pairs to supply to the component
| `hydrate` | `false` | See below | `hydrate` | `false` | See below
| `intro` | `false` | If `true`, will play transitions on initial render, rather than waiting for subsequent state changes | `intro` | `false` | If `true`, will play transitions on initial render, rather than waiting for subsequent state changes
@ -1081,3 +1082,29 @@ const { head, html, css } = App.render({
answer: 42 answer: 42
}); });
``` ```
---
The `.render()` method accepts the following parameters:
| parameter | default | description |
| --- | --- | --- |
| `props` | `{}` | An object of properties to supply to the component
| `options` | `{}` | An object of options
The `options` object takes in the following options:
| option | default | description |
| --- | --- | --- |
| `context` | `new Map()` | A `Map` of root-level context key-value pairs to supply to the component
```js
const { head, html, css } = App.render(
// props
{ answer: 42 },
// options
{
context: new Map([['context-key', 'context-value']])
}
);
```

@ -120,7 +120,7 @@ export function init(component, options, instance, create_fragment, not_equal, p
on_disconnect: [], on_disconnect: [],
before_update: [], before_update: [],
after_update: [], after_update: [],
context: new Map(parent_component ? parent_component.$$.context : []), context: new Map(parent_component ? parent_component.$$.context : options.context || []),
// everything else // everything else
callbacks: blank_object(), callbacks: blank_object(),

@ -74,12 +74,12 @@ export function debug(file, line, column, values) {
let on_destroy; let on_destroy;
export function create_ssr_component(fn) { export function create_ssr_component(fn) {
function $$render(result, props, bindings, slots) { function $$render(result, props, bindings, slots, context) {
const parent_component = current_component; const parent_component = current_component;
const $$ = { const $$ = {
on_destroy, on_destroy,
context: new Map(parent_component ? parent_component.$$.context : []), context: new Map(parent_component ? parent_component.$$.context : context || []),
// these will be immediately discarded // these will be immediately discarded
on_mount: [], on_mount: [],
@ -97,7 +97,7 @@ export function create_ssr_component(fn) {
} }
return { return {
render: (props = {}, options = {}) => { render: (props = {}, { $$slots = {}, context = new Map() } = {}) => {
on_destroy = []; on_destroy = [];
const result: { const result: {
@ -109,7 +109,7 @@ export function create_ssr_component(fn) {
}>; }>;
} = { title: '', head: '', css: new Set() }; } = { title: '', head: '', css: new Set() };
const html = $$render(result, props, {}, options); const html = $$render(result, props, {}, $$slots, context);
run_all(on_destroy); run_all(on_destroy);

@ -0,0 +1,9 @@
<script>
import { getContext } from 'svelte';
const value = getContext('key');
const fn = getContext('fn');
</script>
<div>{value}</div>
<button on:click={() => fn('hello world')} />

@ -0,0 +1,32 @@
export default {
async test({ assert, target, window }) {
const Component = require('./Component.svelte').default;
const called = [];
const component = new Component({
target,
context: new Map([
['key', 'svelte'],
['fn', (value) => called.push(value)]
])
});
assert.htmlEqual(target.innerHTML, '<div>svelte</div><button></button>');
const button = target.querySelector('button');
await button.dispatchEvent(new window.MouseEvent('click'));
assert.deepEqual(called, ['hello world']);
component.$destroy();
},
test_ssr({ assert }) {
const Component = require('./Component.svelte').default;
const called = [];
const { html } = Component.render(undefined, { context: new Map([
['key', 'svelte'],
['fn', (value) => called.push(value)]
]) });
assert.htmlEqual(html, '<div>svelte</div><button></button>');
}
};

@ -13,6 +13,7 @@ import {
shouldUpdateExpected, shouldUpdateExpected,
mkdirp mkdirp
} from '../helpers'; } from '../helpers';
import { set_current_component } from '../../internal';
function tryToReadFile(file) { function tryToReadFile(file) {
try { try {
@ -127,6 +128,8 @@ describe('ssr', () => {
showOutput(dir, { generate: 'ssr', format: 'cjs' }); showOutput(dir, { generate: 'ssr', format: 'cjs' });
err.stack += `\n\ncmd-click: ${path.relative(process.cwd(), dir)}/main.svelte`; err.stack += `\n\ncmd-click: ${path.relative(process.cwd(), dir)}/main.svelte`;
throw err; throw err;
} finally {
set_current_component(null);
} }
}); });
}); });
@ -223,6 +226,8 @@ describe('ssr', () => {
showOutput(cwd, compileOptions); showOutput(cwd, compileOptions);
throw err; throw err;
} }
} finally {
set_current_component(null);
} }
}); });
}); });

Loading…
Cancel
Save