-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
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
Allow "listeners" to be passed into constructor #777
Comments
This makes me think of a use case for adding a |
I can think of three possible solutions off the top of my head, each with downsides: initialisation optionPer the initial proposal: app = new App({
target,
on: {
foo() {
console.log('foo');
}
}
}); One weakness of this approach — though in practical terms, perhaps it doesn't matter — is that there's no equivalent of this: app.on('foo', () => console.log('foo 1'));
app.on('foo', () => console.log('foo 2')); Each event can only have one listener. The other downside is that it necessitates adding generated code to every component: if (options.on) {
Object.keys(options.on).forEach(eventName => {
this.on(eventName, options.on[eventName]);
});
} Not a lot of code, but we've been fairly careful about adding any non-optional code unless there's no other way. So let's see if there's another way... Queued eventsSome event systems allow handlers to receive events that have already happened. Not a huge fan of this approach, it's confusing.
|
Secret option 4 is something that I thought of and that I almost suggested as a reasonable way to do this, without having too much niche API - but from what I could tell, the |
Wouldn't it only really matter for the top-level component though? You don't have an opportunity to attach custom properties to the options for child components. Relatedly, I've wondered about special-casing <Widget on:create='doSomething()'/>
<script>
export default {
methods: {
doSomething() {
// just need to figure out whether this is called before the hook or after...
console.log('this would be tricky to do any other way');
}
}
}
</script> |
Regarding option 4 (and I think what Conduitry said), doesn't the order of execution mean app's oncreate is called after the app's event handler for the nested component's event? E.g: https://svelte.technology/repl?version=1.30.0&gist=615fc3182e53f9d49c312e70376b91f9 So, in the event handler method you can't call options.potato? Or am I missing something? Also, can someone explain a bit more about how the "mount" approach would work, in regards to my use case? If it helps, I could add more info here about what I'm trying to achieve in my app's design, to see if there's a better approach. Or I could post it on SO as a separate question? |
@ScottMaclure it sounds like we're ultimately talking about changes to Svelte itself, so this is an appropriate place to have the discussion. I misunderstood the point about order of execution with nested components — thanks for the demo. What if methods: {
requestData: () => {
- console.log('app requestData, options.potato() needed here?')
+ this.options.potato();
}
} Would that give us the necessary escape hatch? |
Yes, I think it would! Background to this use case: I've rolled my own routing, which is data-driven (e.g. app.set({ route: blah }). One use case breaks the design - when you refresh the browser with the URL pointing to this particular page - the app hasn't been created yet so the listeners aren't defined at that point. I've written 2 demo apps in Svelte so far, following similar principles, and bumped into the same problem in both, so at least from my limited experience it sounds like a worthy issue to address. The key technical design idea was to avoid injecting the store.js or other objects into the component hierarchy.... so There are other approaches I could take for my app without needing a change to Svelte - for example, must my app actually wait until I navigate to that "page" component to lazily load data? What if I just start loading the data in the background, no matter what the page? Then I can just write a promise and call app.set, and the "page" component inits in a loading state. But would that scale if I had 50 similar pages in my app? Rich, your HN demo in REPL has a similar feature with the async hashchange function, the only difference is I pulled logic like that out of the components completely. Edit: here's an example nested component: |
As of 1.34, you can access |
Use case: I like to create my "app" component, then use
app.on()
API to bind event handlers on component events. Example:Problem: In a nested component's
oncreate
method I might callthis.fire('foo')
but it's too early to useapp.on()
with and I miss that event.So... what if I could pass in a map of event names -> functions to the "app" component's constructor? Or is there a better approach?
The text was updated successfully, but these errors were encountered: