Ken M
Ken M

Reputation: 83

Dart Web UI: How do I get a reference to an item within in a web component?

If I add a number of web components to my app as in myapp.html below:

<head>
  <link rel="components" href="package:xclickcounter/xclickcounter.html">
</head>
<body>
   <div id="container1"><x-click-counter></x-click-counter></div>
   <div id="container2"><x-click-counter></x-click-counter></div>
   <div id="container3"><x-click-counter></x-click-counter></div>
   <div id="container4"><x-click-counter></x-click-counter></div>
   ...
</body>

And I have number of elements in my web component as in xclick-counter.html below:

<html><body>
  <element name="x-click-counter" constructor="CounterComponent" extends="div">
    <template>
      <button id="button1" on-click="increment()">\\\Increment me</button>
      <button id="button2" on-click="decrement()">Decrement me</button>
      <span>(click count: {{count}})</span>
    </template>
  </element> 
<!-- more below... -->
</body></html>

How do i get a reference to #button2 in the web component in #container3 from myApp.dart?

I would expect that i can get a reference as below but my reference turns out to be null:

var reference=document.query('#container1').query('#button2');

Upvotes: 1

Views: 367

Answers (1)

Seth Ladd
Seth Ladd

Reputation: 120439

Generally, you shouldn't try to do that. :) The Shadow DOM is an encapsulation boundary, and the custom element's template contents should be hidden as implementation details. Think of a custom element like a class. You don't want to reach into a class and see the private fields, just like you don't want to reach into a custom element and see the nodes inside the Shadow DOM.

Having said that, I'd like to make a suggestion:

Web UI currently does not keep IDs (from inside custom elements) unique on the page. For every instance of x-click-counter, the page will have a duplicated button1 and button2 elements.

I opened https://github.com/dart-lang/web-ui/issues/492 to track the issue.

The workaround is to use classes instead of IDs. Then, you can give the host element an ID, as you did in your code. Try changing to this:

  <element name="x-click-counter" constructor="CounterComponent" extends="div">
    <template>
      <button class="button1" on-click="increment()">\\\Increment me</button>
      <button class="button2" on-click="decrement()">Decrement me</button>
      <span>(click count: {{count}})</span>
    </template>
  </element> 

Upvotes: 2

Related Questions