Reputation: 28760
How can I pass dynamic arguments to the component helper.
In production, I am iterating over a json hash that will render different components with different attrs each time.
I have a scaled down example in this jsbin.
I am returning this json hash:
columns: Ember.computed('people.[]', function() {
return this.get('people').map(function(person){
return {
component: 'x-person',
attrs: {
person: person
}
};
});
})
That I then iterate over and try and pass the arguments into the component:
{{#each columns as |column|}}
{{component column.component column.attrs}}
{{/each}}
The component is getting created but the attributes are not set.
How can I properly pass the arguments to the component helper?
Upvotes: 4
Views: 2703
Reputation: 633
If you want more flexibility like not having to update the way each attr is used in the dynamic component, I suggest this:
Create an initializer to extend Ember.Component
import Ember from 'ember';
var Component = {
loadAttrsHash: Ember.on('didReceiveAttrs',function(attrs){
if(this.get('attrsHash')){
let hash = this.get('attrsHash');
Object.keys(hash).forEach(key=>{
this.set(key,hash[key]);
});
}
}),
};
export function initialize(/* application */) {
Ember.Component = Ember.Component.extend(Component);
}
export default {
name: 'component',
initialize
};
Then you can create dynamic components with an attrs hash
{#each columns as |column|}}
{{component column.component attrsHash=column.model}}
{{/each}}
Then you can access attrsHash.person, simply with {{person}} in the child component just as if it was passed directly.
This way, the component is more durable as it can be used with direct attributes as well as attrsHash
, and should update whenever attrsHash changes.
Upvotes: 6
Reputation: 18682
You have to follow some convention to pass all data to dynamic components using model property.
Columns:
columns: Ember.computed('people.[]', function() {
return this.get('people').map(function(person){
return {
component: 'x-person',
model: {
person: person
}
};
});
})
Template:
{#each columns as |column|}}
{{component column.component model=column.model}}
{{/each}}
And in all components that are dynamically created you should access properties via model
attribute passed to component. So, if something were color
before it should now become model.color
etc.
Upvotes: 3