Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot access content (childNodes) in nested Polymer Element #414

Closed
tomalec opened this issue Feb 4, 2014 · 6 comments
Closed

Cannot access content (childNodes) in nested Polymer Element #414

tomalec opened this issue Feb 4, 2014 · 6 comments

Comments

@tomalec
Copy link
Contributor

tomalec commented Feb 4, 2014

I try to nest one component into another, and access content (light DOM) given to outer element one in inner one.

<polymer-element name="x-foo" noscript>
  <template>
    <h1>Foo</h1>
    <content></content>
  </template>
</polymer-element>

<polymer-element name="x-bar" noscript>
  <template>
    <h1>Bar</h1>
      <x-foo>
          <content></content>
      </x-foo>
  </template>
</polymer-element>

<x-foo>
  <p>Content</p>
</x-foo>
<x-bar>
  <p>Nested content</p>
</x-bar>

seems to render fine.
However, I cannot get <p>Nested content</p> as x-foo content:

Polymer('x-foo',{
  ready: function(){
    console.log(
      this.children,
      this.shadowRoot.querySelector('content').getDistributedNodes()
    );
  }
});

Full example is here: http://jsfiddle.net/tomalec/T7k3C/2/

Is this a bug, or I should access it some other way?

@sorvell
Copy link
Contributor

sorvell commented Feb 4, 2014

This is expected. The 'ready' method cannot be used with code that depends
on the state of external elements, e.g. children or distributed elements or
parent. The element is not guaranteed to be in the dom when ready is
called. Instead, ready is the signal that the element's internal state is
ready for use, its shadowRoot, event listeners, property observers, and
bindings.

Instead you should use the 'attached' method for this type of thing. When
attached is called, the element is in the dom tree. Further, it's best to
go asynchronous when accessing external dom. This ensures any element
upgrades have been processed. This way you are independent of upgrade
ordering. (Note: we'll probably make a helper method for this in polymer so
it's a little more clear what to do).

Here's an example: http://jsbin.com/oGECArO/1/edit (removed the textNodes
for clarity)

On Tue, Feb 4, 2014 at 8:28 AM, Tomek Wytrębowicz
[email protected]:

I try to nest one component into another, and access content (light DOM)
given to outer element one in inner one.

Foo

Bar

Content

Nested content

seems to render fine.
However, I cannot get

Nested content

as x-foo content:

Polymer('x-foo',{
ready: function(){
console.log(
this.children,
this.shadowRoot.querySelector('content').getDistributedNodes()
);
}});

Full example is here: http://jsfiddle.net/tomalec/T7k3C/2/

Is this a bug, or I should access it some other way?


Reply to this email directly or view it on GitHubhttps://github.com//issues/414
.

@tomalec
Copy link
Contributor Author

tomalec commented Feb 5, 2014

Thanks a lot @sorvell.
My bad, I totally missed that flow.

Is this also the reason why firstChild for nested element is <content> instead of <p> (as for outer one)?
Should I always use this.shadowRoot.querySelector('content').getDistributedNodes(), or is there something shorter? Especially, that for getDistributedNodes I would need to filter Text nodes.
http://jsbin.com/oGECArO/4/edit

@ebidel
Copy link
Contributor

ebidel commented Mar 4, 2014

We have domReady now that will make it out in the next release. Can we close?

@sorvell
Copy link
Contributor

sorvell commented Mar 4, 2014

Sure. This is resolved by domReady.

@sorvell sorvell closed this as completed Mar 4, 2014
@sjmiles
Copy link
Contributor

sjmiles commented Mar 5, 2014

Should I always use this.shadowRoot.querySelector('content').getDistributedNodes(), or is there something shorter?

It's best to give the content node an id and use $ to reference it, e.g.:

<content id="content">
...
this.$.content.getDistributedNodes()

This allows your content node to be indirected from this.shadowRoot which may not refer to the right root if the element has been subclassed.

@kristianmandrup
Copy link

Could you have a look at this please :)

PolymerElements/paper-scroll-header-panel#50 (comment)

raphael-kikuchi added a commit to raphael-kikuchi/iron-data-table that referenced this issue Aug 9, 2017
By sorvell: (Polymer's team member)

"[...] The 'ready' method cannot be used with code that depends
on the state of external elements, e.g. children or distributed elements or
parent. The element is not guaranteed to be in the dom when ready is
called. Instead, ready is the signal that the element's internal state is
ready for use, its shadowRoot, event listeners, property observers, and
bindings.

Instead you should use the 'attached' method for this type of thing. When
attached is called, the element is in the dom tree. Further, it's best to
go asynchronous when accessing external dom. This ensures any element
upgrades have been processed. This way you are independent of upgrade
ordering. [...]"

more info: Polymer/polymer#414
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants