Closed BennyAlex closed 7 years ago
Here is a twiddle with your requirements: https://ember-twiddle.com/bd4821f05452b8e17b09e6dba3b5756f?openFiles=components.parent-component.js%2Ctemplates.components.child-component.hbs
Let me know if I missed something.
@miguelcobain thank you. I didnt knowed that when using
{{yield (hash
child=(component "child-component" disabled=disabled parentComponent=this)
)}}
and having a default value in the child component:
import Ember from 'ember';
import { ChildMixin } from 'ember-composability-tools';
export default Ember.Component.extend(ChildMixin, {
tagName: 'li',
disabled: 'not disabled',
});
and I call
{{#parent-component as |p|}}
{{p.child}}
{{/parent-component}}
disabled will be undefinded, and not the default value from child component
Right.
When you do that disabled=disabled
you're basically overwriting the disabled property to undefined
, because disabled
isn't defined in the parent context.
I overlooked the right context.
I am really sorry for troubled you 😞
When I try to filter the childs, I get "Assertion Failed: You modified "activeTabs" twice in a single render". What can I do?
activeChilds: computed('childComponents.@each.disabled', function () {
if (this.get('childComponents')) {
return this.get('childComponents').filterBy('disabled', false);
}
}),
@BennyAlex it is very common to fall on that trap when using this kind of composability. This happens because the act of rendering a component changed something that was already rendered.
You should try to avoid rendering things in the parent that depend on properties of the children. Keep in mind that I don't mean you can't use properties from the children. You can use them internally in the component freely, just don't use them to render something. With that being said, sometimes you absolutely need to do so. One trick that I frequently use is to render those things after I yield.
In your example, instead of doing
<div>There are {{activeChilds}} active children.</div>
{{yield childrenComponentsHere}}
you could do
{{yield childrenComponentsHere}}
<div>There are {{activeChilds}} active children.</div>
You may face a styling issue then because the parent DOM is after the children DOM. Try to use flex-order
or something similar to correct that.
@miguelcobain wow, looks like there are a lot of dangers... Your solution works fine, thanks for that!
This addon wasn't born exactly for this scenario. When components don't render DOM (like in the ember-leaflet case), this isn't a problem. It can be very useful nonetheless.
But there arent any other ways to archive it, or?
Rendering something that depends on children components state has to either be done through services or contextual components, afaik. This is just a tiny abstraction on top of contextual components. That way you don't to manage component registration/unregistration yourself, etc.
@miguelcobain I have a strange bug:
My childComponents have got a 'disabled' attribute, and it's false by default.
Now, try to access the disabled property on the first child, it will be undefinded.
will log with 3 child components: