Walid Ammar
Walid Ammar

Reputation: 4126

Cannot select elements inside "auto-binding" template

I have created some custom elements, now I'm writing tests for them.

I wanted to use "auto-binding" because I have plenty of attributes that needs to be bound among my elements.

Unfortunately I cannot query any element inside the template.

Here is some code.

    <template id="root" is="auto-binding">
        <dalilak-data-service id="dds" regions="{{regions}}"></dalilak-data-service>

        <dalilak-regions-handler id="drh" regions="{{regions}}" flattendedRegions="{{flattendRegions}}" descendantsRegionNames="{{descendantsRegionNames}}" regionsByNameId="{{regionsByNameId}}"></dalilak-regions-handler>

    </template>

In the test script I have tried the following

   drh =  document.querySelector('#drh');
   suite('dalilak-regions-handler', function() {
        test('handler initialized', function() {
            assert.ok(drh);
        });
   });

Also tried this:

   drh =  document.querySelector('* /deep/ #drh');  // or '#root /deep/ #drh'     
   suite('dalilak-regions-handler', function() {
        test('handler initialized', function() {
            assert.ok(drh);
        });
   });

But none of them worked.

Note without the template I can query my custom elements.

Upvotes: 2

Views: 261

Answers (2)

Scott Miles
Scott Miles

Reputation: 11027

auto-binding templates stamp asynchronously, I expect your problem is that you need to wait for the template to stamp before querying for elements.

The template fires a template-bound event when this happens, so you can use code like this:

addEventListener('template-bound', function() {
   drh =  document.querySelector('#drh');
   ...
});

Of course, this means your testing infrastructure will need to understand how to handle asynchrony, which can be a concern.

Upvotes: 3

williamcodes
williamcodes

Reputation: 7236

Where possible, it is best to avoid the /deep/ selector. That is a nuclear option and can return unexpected results because it pierces all shadow DOMs. It also won't work for your auto-binding template because its contents are inside a #document-fragment, not a #shadow-root. Instead, try querying the #document-fragment itself. This preferable because you are limiting your query to the scope of your template, which is much more precise.

var template = document.querySelector('#root');
var drh = template.content.querySelector('#drh');

Upvotes: 2

Related Questions