在Ember.js中,我正在设计一个上下文组件,并希望处理子组件不存在的情况,而是显示一些常规信息。
但是我不知道如何检测模板中何时存在标签。使用yield和hash,如果标签不存在,则不会显示任何内容,仅此而已...
第一种情况:所有子组件均存在
<ParentComponent as |parent|>
<parent.mandatoryChild>
Something
</parent.mandatoryChild>
<parent.child>
Something else
</parent.child>
</ParentComponent>
第二种情况:parent.child
组件不存在
<ParentComponent as |parent|>
<parent.mandatoryChild>
Something
</parent.mandatoryChild>
{{! no parent.child here }}
</ParentComponent>
我的父组件模板是:
<div class="mandatoryChild-wrapper-class">
{{yield
(hash
mandatoryChild=(component this.mandatoryChildComponent)
)
}}
</div>
<div class="mandatoryChild-wrapper-class">
<!-- how to show some generic information when child is not present in the callee template? -->
{{yield
(hash
child=(component this.childComponent)
)
}}
</div>
<div class="mandatoryChild-wrapper-class">
{{yield (hash mandatoryChild=(component this.mandatoryChildComponent))}}
</div>
<div class="mandatoryChild-wrapper-class">
{{#if this.childComponent}}
{{yield (hash mandatoryChild=(component this.childComponent))}}
{{else}}
generic information
{{/if}}
</div>
有不同的模式可以做到这一点。
最简单的方法是在父组件上使用一个参数。在这种情况下,消费者决定渲染可选子项,例如:<ParentComponent @withOptionalChild={{true}} />
您还可以使用更高级的解决方案。例如。如果可选的子组件已注册,则可以在父组件上注册自己;如果已删除,则可以注销。您应该对用户透明设置注册。例如。通过将register
和unregister
参数传递给产生的可选子级,该子级在didInsertElement
和willDestroyElement
挂钩中调用该子级。请注意,使用该解决方案时,将不会在与父组件相同的运行循环中呈现可选子项,而是在一个运行循环之后呈现该可选子项。用户可能会看到闪烁。它还可能会引入其他计时问题。
我想这些是该情况下最常见的模式。第一个例子是Ember Contextual Table。它使用defaultHeader
属性来控制用户是否能够以组件的块形式自定义标题。第二种模式的一个非常高级的示例是Ember Leaflet
在大多数情况下,我会推荐该论点。它可能会增加一些样板,但实现和维护起来更容易。