简体   繁体   中英

Get an Ember Component from the DOM Element

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?

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];
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM