Mario
Mario

Reputation: 660

Ember tagless component innerhtml

I have a tagless component in Ember and want to have the innerHtml (this.element) on a lifecycle hook (for example the didRender). When I use this.element the value is always null. When I add a tagname to the component (tagName: 'div') I have the innerHtml of the component with this.element, but can I get the innerHtml without setting the tagName?

Upvotes: 5

Views: 1362

Answers (2)

Ed4
Ed4

Reputation: 2305

this.element does not give you innerHTML, it gives you a real HTML Element. A tagless component, by definition, doesn't have any Element of its own. So this.element is necessarily null.

The biggest reason we haven't added an equivalent property for retrieving a Range (which is what you'd need to represent a tagless component's area of the DOM) is that unlike this.element, the Range could change through the lifetime of the component. Making it fully observable would be expensive, and leaving it not-observable would make it really easy to create bugs.

Most of the common use cases are covered by what Gaurav suggested: explicitly labeling the elements you really want to find and accessing them via querySelector or querySelectorAll.

If you're doing something really fancy, and you understand that it's only a snapshot that can go stale, the escape hatch is Ember.ViewUtils.getViewBounds. It's not marked public, but it is depended on by official projects like Ember Inspector, so we absolutely would not break it without warning. Like any heavily-used non-public API, we would issue a deprecation warning and wait a full LTS cycle.

In the case of Ember.ViewUtils.getViewBounds, a strong case can be made for just marking it public, and if somebody writes an RFC to that effect I think we can get consensus on that.

Upvotes: 9

Gaurav
Gaurav

Reputation: 12796

Yes, this is broken. See https://github.com/emberjs/ember.js/issues/13627 for more details.

A workaround has been posted here: https://github.com/emberjs/rfcs/issues/168 However, it uses private apis and may break in future versions without warning.

My recommendation is to either use an element via tagName so this.element exists, or to place a class on the component's parent element so that you can use document.querySelector('.class-name').innerHTML -- but this requires that the parent element be known.

Upvotes: 2

Related Questions