-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace target instead of appending to it #1549
Comments
This conversation may still be relevant.
|
Also I didn't tested the latest version but the last time I tried I couldn't render the target content as a default |
This is a funny one :) I ran into this while trying to set up hot reloading for svelte. |
The slot functionality relies on you being in the Svelte context. So you will need to wrap your component that contains the slot in a small svelte "app" and mount that. |
That's not quite true — there is an API for slots, though I think we haven't got round to documenting it. You can do this: const thing = new Thing({
target,
slots: {
default: someDomNodeOrFragment,
foo: someOtherDomNodeOrFragment
}
}); If you're compiling your components with Otherwise, using a helper to clear out the existing DOM is the best way forward — it's not something we should add to Svelte itself, since it's extra code for something that most people won't need. |
OK, that's super useful. Thanks for setting me straight. Sorry @constgen for poor information. |
Closing this, as I don't think there's anything else that needs to happen. Comment if you think otherwise. |
@Conduitry maybe add a note containing the |
For future reference.
Seems like this API was for Svelte v2. |
You can also simply do this to replace the target:
This prepends the new component just before the target element (in the target's parent), and then removes the target. Relevant documentation on Probably not a good idea to use with |
@Lindsay-Needs-Sleep Nice! What about keeping the target attributes (name, id etc. )? |
@azmeuk My use case didn't require that, so I didn't play with it. eg. something like function replaceTarget (target) {
// Manually read the attributes you want tp preserve
var name = target.name;
// You can pass the value to the svelte component's props if your component has something like "export let myName;"
const component = new MySvelteComponent({
target: target.parentElement,
anchor: target,
props: {
myName: name,
},
});
target.remove();
} Since a svelte component doesn't necessarily have a single root node, you would have to do something pretty extra to decide which element within your svelte component to apply the attributes to. |
I ended with those utility functions: function replaceTargetByComponent(target, Component, options) {
const frag = document.createDocumentFragment();
var props = {
name: target.name,
id: target.id,
...target.dataset,
}
const component = new Component( Object.assign( {}, options, {
target: frag,
props: props,
} ));
target.replaceWith( frag );
}
export function replaceClassByComponent( classname, Component, options ) {
const targets = document.getElementsByClassName(classname)
for (const target of targets) {
if (target.replaceWith) {
replaceTargetByComponent(target, Component, options);
}
}
}
export function replaceIdByComponent( id, Component, options ) {
const target = document.getElementsById(id)
if (target && target.replaceWith) {
replaceTargetByComponent(target, Component, options);
}
} The good thing being one can dynamically pass property to the components by setting HTML data attributes. |
Hi, when I do
new MyComponent({target: document.getElementById('someId')})
then the new component gets added to the element instead of replacing it.I would love to have a way to replace the target, f.x
new MyComponent({target: document.getElementById('someId'), replace: true})
. This would give my users a better experience in situations where I'm adding Svelte components to content that they already see in their browser.The text was updated successfully, but these errors were encountered: