-
-
Notifications
You must be signed in to change notification settings - Fork 4.5k
Get access to a component's own class in the script and script module ("$$self" or else) #5517
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
Comments
What would |
There's been 4 times <script>
import { getContext } from "svelte";
import MyPageComponent from "./Component.svelte";
getContext("page-state").push(MyPageComponent);
</script> Not being able to push the component itself directly meant I had to make a proxy and an actual component for each page, using <script>
import { getContext } from "svelte";
getContext("page-state").push($$self);
export let rendered = false;
</script>
{#if rendered}
<!-- MyPageComponent content -->
{/if} Second situation is kind of meta, I needed to add every mounted component in a centralized Set, $$self would've come in handy ( had to either write a unique hash in |
@pngwn Different use case that Will try to clarify with some dummy code. Current option (bind and watch the binding every time I use Grid):
Like to have (just pass them in and let Grid manage itself):
Update: Have got it working using |
The svelte "module context" tutorials demonstrates a pattern for using a module context to manage components that should be controlled as a group. This is accomplished using
Currently there isn't a good way to get to set
This is super janky and I'm not sure you end up with a reference to the correct component. Some potential solutions that may work well:
|
We've run into this when trying to implement type safety for component callbacks. The only way to get the type of the current component is to import itself. |
Another use case: <!-- InfoPopup.svelte -->
<script context="module">
export function openInfoPopup() {
return new $$self({
target: document.body,
});
}
</script>
<div class="popup">Hello World!</div> There's currently no portable way to do this, AFAICS. I've found a workaround when using Webpack: A built-in keyword like |
I came here looking for an official solution to referencing the self component from the script block. Oddly, $$self is the first argument of the instance. But results in illegal variable name validation error on server side. For client only reference to self, this is what I do:
output: client: Pages (SvelteComponentDev) |
I'm curious, Is this legal? Will it change? I can't find a reference to it in the svelte docs; I'll use it anyway, but I'm hoping the svelte team doesn't patch it. Please let me know where you discovered the "arguments" variable. |
I can't speak for legalities, and I certainly hope they don't patch it. In fact, I'd rather the team come up with something like $$self instead of me using hacky ways like 'arguments' or 'get_current_component'. How I discovered the arguments is a combination of svelte/internal and the compiled version of the svelte component: This line in svelte/internal calls the instance of the component: svelte/src/runtime/internal/Component.ts Line 110 in 709264a
This is what the internal function calls on the compiled version of your svelte component: The first argument is the component aka $$self we can't use/access in svelte land, second argument is the $$props which we can access in svelte land. So svelte land scripts get put into this instance function, and you can access the arguments once svelte gets compiled to vanilla javascript. But again this only works on client side, so you got to protect it with a client/browser check. I use !import.meta.env.SSR but could wrap it in onMount arrow function if immediate action/manipulation on the self component is not needed for your use-case. |
I've run in to a use case when using the modals in @svelte-put. I have a module scope function to open the dialog component from various places. But need to supply the svelte class component as a prop. To achieve this currently, i import the component to itself. |
This is a serious issue. Having to access a reference to an instance itself through the DOM wit conditional rendering is not a good solution (as it effectively creates the component TWICE). The |
Components/modules can import themselves. <!-- App.svelte -->
<script>
import App from './App.svelte';
</script> |
But we do have the conditional rendering again. It would be nice to have something like |
I still don't get the reasons. Moreover, it seems here are mixed component class (which can be obtained via module self-import) and the current component instance.
<script>
export let name;
</script>
{#if !name}
<svelte:component this={$$self} name={'world'} />
{:else}
<h1>hello {name} !</h1>
{/if} What's wrong with <script>
export let name;
</script>
<h1>hello {name || 'world'} !</h1> or Talking about @mbacon-edocs case, split the view and model+controller into separate entities and then you can pass the model+controller instance to the extensions. Talking about popovers, I find it more convenient to use them as functions (just mount to body) or actions (when located around a certain element). And with Svelte 5 Snippets, we can even use popovers with slots via these approaches.
|
This is a proposal to add a
$$self
( or else ) reserved keyword that resolves into a reference to a component's own class, such as to make the following output<h1>hello world !</h1>
Now that usecase is already covered by
svelte:self
, and even then there will always be a way to sneak that reference in to the script block or proxy it through other script modules ( see below ), yet I happen to find myself needing$$self
more than any other supported "escape hatch"$$keyword
, so while the argument for such keyword is definitely not compelling, I do think that it would be a nice to haveScript block workaround at component instantiation
For typescript users, the only way to use a component in any other way but as inlined in another component's xhtml markup is by exporting it through the script module of a proxy component, as importing from a non
.svelte
file is not yet supported by the vscode pluginThe text was updated successfully, but these errors were encountered: