Reputation: 4059
In Ember.js, I'm designing a contextual component and want to handle the case where a child component is not present and show some generic information instead.
But I can't figure out how to detect when the tag is present or not in the template. Using yield and hash, if the tag is not present, nothing is shown and that's all...
First case: all child component are present
<ParentComponent as |parent|>
<parent.mandatoryChild>
Something
</parent.mandatoryChild>
<parent.child>
Something else
</parent.child>
</ParentComponent>
Second case: the parent.child
component is not present
<ParentComponent as |parent|>
<parent.mandatoryChild>
Something
</parent.mandatoryChild>
{{! no parent.child here }}
</ParentComponent>
My parent component template is:
<div class="mandatoryChild-wrapper-class">
{{yield
(hash
mandatoryChild=(component this.mandatoryChildComponent)
)
}}
</div>
<div class="child-wrapper-class">
<!-- how to show some generic information when child is not present in the callee template? -->
{{yield
(hash
child=(component this.childComponent)
)
}}
</div>
Upvotes: 1
Views: 113
Reputation: 6338
There are different patterns to do that.
The easiest one is using an argument on the parent component. In that case the consumer decide to render the optional child, some thing like: <ParentComponent @withOptionalChild={{true}} />
You could also use more advanced solutions. E.g. the optional child component could register itself on the parent component if it's registered and unregister if it's removed. You should setup the registration transparent to the consumer. E.g. by passing register
and unregister
arguments to yielded optional child, which is calling that ones in didInsertElement
and willDestroyElement
hooks. Be aware that with that solution the optional child will not be rendered in same runloop as the parent component but one runloop later. That might be visible to the user as flickering. It might also introduce other timing issues.
I guess these are the most common patterns for that scenario. An example for the first one is Ember Contextual Table. It uses a defaultHeader
property to control if the user is able to customize the header in component's block form or not. An very advanced example of the second pattern is Ember Leaflet
I would recommend the argument in most cases. It may add some boilerplate but it's way easier to implement and maintain.
Upvotes: 1
Reputation: 4015
<div class="mandatoryChild-wrapper-class">
{{yield (hash mandatoryChild=(component this.mandatoryChildComponent))}}
</div>
<div class="mandatoryChild-wrapper-class">
{{#if this.showOptionalChild}}
{{yield (hash child=(component this.childComponent))}}
{{else}}
generic information
{{/if}}
</div>
Upvotes: 0