-
-
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
Functionality clarification - {{yield}}ing in multiple places #17240
Comments
After thinking about this some more I think I get why this works.
We are actually yielding out two times and rendering the block two times but because of the fact that blocks for properties that aren't yielded out will be ignored we will only render the ui once. So this seems like it is supposed to work that way. But this raises the question if we should do it this way? Are there any drawbacks when yielding out multiple times from one component? Is this future proof? I realized that this might be something better discussed in discuss happy to move the discussion there if here's not the right place. |
Relevant discuss post: https://discuss.emberjs.com/t/using-yield-for-multiple-nested-components/9126/2 I'm also interested to hear if this is the intended behaviour and can be considered safe to use, since we use it in multiple projects already 😁. |
@LevelbossMike What I've observed is that the Ember docs to provide a commitment to behavior, I tagged this as a cc/ @emberjs/learning-team-managers |
This seems pretty surprising, and I believe does not work in Ember 3.6.0. This was fixed by #17135.
I realize that this is how it seems, but is actually not what is happening. The yielded block is actually being invoked twice and combined with the bug mentioned above (fixed in 3.6) means that the "alternate" is simply ignored (as if you had done |
@LevelbossMike yesterday I worked on a component which at first glance it seemed like a good idea to use multiple yields, but after working on it for a while a single yield was fine. What I did was create multiple nested components for the HTML structure I wanted to use and those components each had their own I'm curious if you have tried a different approach, e.g. "Contextual Components" vs. a solution for multiple |
I believe that the initial question has been addressed (the specific technique in the blog post is essentially taking advantage of a bug that has been fixed), so I'm going to close this for now (though I'm super happy to continue to the conversation). |
@rwjblue I have a question around the multiple yielded blocks. Even if they're empty, is that a potential performance bottleneck? The technique described in the blog post can still be used if we include the |
I've found the same, it still works on Ember 3.24 it seems when using component helper. Modified the example from the OP; // my-component.hbs
{{#if @isLoading}}
<div class="loading">
{{yield (hash loading=(component 'x-loading'))}}
</div>
{{else}}
<span class="loaded">
{{yield (hash loaded=(component 'x-loaded'))}}
</span>
{{/if}} <MyComponent as |me|>
<me.loading> loading... </me.loading>
<me.loaded> loaded!! </me.loaded>
</MyComponent> Can we rely on this behaviour when using the component helper instead? It's such a handy way to write components |
That being said, I've managed to re-write my code to use the new yieldable named blocks (Ember 3.25+). Here's what that looks like, in case anyone finds it useful; // my-component.hbs
{{#if @isLoading}}
<div class="loading">
{{yield (component "load-indicator") to="loading"}}
</div>
{{else}}
<span class="loaded">
{{yield to="loaded"}}
</span>
{{/if}} <MyComponent>
<:loading as |LoadIndicator|> loading... <LoadIndicator /> </:loading>
<:loaded> loaded!! </:loaded>
</MyComponent> You can yield components instead of where I've used loadingPercent too |
Hi and sorry for the strange title.
I have come across this blog-article that suggest a way to implement "multiple"-yields in a component.
https://dockyard.com/blog/2018/11/26/how-to-yield-an-ember-component-in-multiple-places
This is a very powerful pattern and allows entirely new component abstractions - before embracing I want to make sure that this is intended behavior and it won't break in future releases before using in my own applications.
The blogpost suggests a clever solution to the problem at hand (wanting to define named blocks in a component) and it really works the way the author describes. Several things are surprising in the code example provided:
https://ember-twiddle.com/034c04f68f0c3082d95104586e52f1e4?openFiles=templates.components.fancy-toolbar.hbs%2C
Example for 1.
I thought this only worked if we were using the
component
-helper. I'm pretty certain that was needed in the past but this might have changed along the way. Is this intended behavior or only works by accident?Example for 2 - directly taken from the blog post
https://ember-twiddle.com/034c04f68f0c3082d95104586e52f1e4?openFiles=templates.components.fancy-toolbar.hbs%2C
To me it's very surprising that hashes are being merged from multiple yields. It really doesn't fit the mental model that I had for ember-templates but that is most likely because I was missing something. If that is intended behavior I suppose we should clarify this in the guides. I can't remember ever coming across this functionality in the past.
Playing around with this a bit I found another surprising behavior.
this seems to be treated the same way as an undefined property but will throw when we try to render a component like usual:
This is nice because it allows patterns like this where you define a loading-component and a loaded-state component side-by-side but it's still surprising.
I guess this works because the rendering engine tries to look up a value instead of a helper but this is surprising behavior still.
TLDR;
https://dockyard.com/blog/2018/11/26/how-to-yield-an-ember-component-in-multiple-places discusses surprising behavior of Ember's templating layer. This allows powerful abstractions for components but it's not clear if this only works by "accident" or is intended behavior. Before embracing this pattern we should make it clear if this behavior will be supported in future releases.
The text was updated successfully, but these errors were encountered: