Reputation: 333
I have an Ember Component as So...
export default Ember.Component.extend({
didInsertElement: function() {
this.$().sortable({
connectWith: '.droppable-box',
receive: (e, ui) => {
}
});
},
tagName: 'ul',
classNames: ['droppable-box', 'list-unstyled']
});
The elements inside the sortable components are also components...
export default Ember.Component.extend({
tagName: 'li'
});
The receive event is fired whenever a element is moved into a sortable component.
I am given the DOM element, but I want to get access to the instance of that Ember Component. Any ideas?
Upvotes: 1
Views: 1875
Reputation: 2922
There is a cleaner way to do this, but uses Ember private API.
The root element of the Ember.Component is assigned an id. You can use this id to lookup the component.
// Ember 1.x
Ember.View.views[id]
// Ember 2.x
container.lookup('-view-registry:main')[id]
I do believe there is an instance of the container attached to components.
Upvotes: 1
Reputation: 167
This is not the cleanest solution, but it should work.
In your child component add the following lifecycle hooks:
//components/child-component.js
...
registerRow: Ember.on('willInsertElement', function () {
this.attrs.onRegister(this.get('elementId'), this);
}),
unregisterRow: Ember.on('willDestroyElement', function () {
this.attrs.onUnregister(this.get('elementId'));
}),
In the parent template, pass the action handlers to all child components:
//components/parent-component.hbs
{{#each children as |child|}}
{{child-component onRegister=(action "registerChild") onUnregister=(action "unregisterChild")}}
{{/each}}
In the parent component, create a dictionary to store child components indexed by their elementId:
//components/parent-component.js
...
children: null,
initChildren: Ember.on('init', function () {
this.set('children', {});
}),
actions: {
registerChild(elementId, child) {
this.children[elementId] = child;
},
unregisterChild(elementId) {
delete this.children[elementId];
}
}
Now, to access components from your jQuery callback, do:
// Presuming ui is a DOM element
receive: (e, ui) => {
let component = this.children[ui.id];
}
Upvotes: 4