Nicholas Kyriakides Nicholas Kyriakides - 4 months ago 31
Javascript Question

Accessing element attributes before Polymer element registration

I'd like to declare attributes directly on a Polymer element, which are then passed inside the element and are readable/accessible outside of the element script.

I'd like to use the values of such attributes for deciding how to register the element.




tl;dr

I'm having an issue where I need to register an element some time after the whole page has loaded - i.e I want to manually register the element.

A solution for registering elements on demand:



<dom-module id="foo-element">
<template>
<span> Foo element </span>
</template>
</dom-module>

<script>
window.addEventListener("app-ready", function() {
"use strict";

Polymer({

is: "foo-element",

properties: {
//..... rest of element properties, methods, etc


Explaining what I'm doing above:


  • Instead of using
    HTMLImports.whenReady(<element-registration-code>)
    , I use
    addEventListener(event, <element-registration-code>

  • I broadcast
    app-ready
    when I want the registration to happen

  • This allows me to register the element, on-demand



The reusability problem of the above solution



This poses a severe reusability problem - while this element in one of context needs to be registered at some specific point in time, in other context it might not - it should register itself using the standard
HTMLImports.whenReady(<elementCode>)
method.

An ideal example:



<!-- Registers automatically when `HTMLImports` are ready, the "regular" way-->
<foo-element></foo-element>

<!-- Registers only when it picks up an `app-ready` event-->
<foo-element no-auto-register register-on-event="app-ready"></foo-element>


and the element could look something like this:

<dom-module id="foo-element">
<template>
<span> Foo element </span>
</template>
</dom-module>

<script>

// if `no-auto-register` is set on the element,
// do not use `HTMLImports.whenReady()` and use
// `addEventListener` to register when an event
// with the value of `register-on-event` property fires.

</script>


Long story, short



Is there any way to declare a flag/property/attribute directly on the element which would decide how the registration should happen?

Answer

Passing an attribute to element might not work as element needs to be in ready state for that. Below are three ways that might help you with what you are trying

One way to lazy register your elements in Polymer is to use Polymer.Class instead of Polymer constructor. This way until you register your element manually it will not get rendered. Below is an working example of same.

<base href="https://polygit.org/components/">
<script src="webcomponentsjs/webcomponents-lite.js"></script>
<link rel="import" href="polymer/polymer.html">

<dom-module id="poly-form">
  <template>
    <style></style>
    I am parent Element
    <div>
      <button onclick='register()'>Save</button>
    </div>
    <show-form></show-form>
  </template>
</dom-module>
<script>
  Polymer({
    is: 'poly-form',
  });

  //element to lazy register
  var showForm = Polymer.Class({
    is: 'show-form',
    ready: function() {
      this.textContent = 'I am working...';
    }
  });

  function register() {
    var form = document.querySelector('poly-form');

    //lazy register the element
    document.registerElement('show-form', showForm);
  }
</script>


<poly-form></poly-form>

In this example show-form element does not render until the button is clicked.

Note I've never really tried this with element containing dom.

Second way this should also be possible with importHref method.

Third way is global setting lazy-register where element gets register only when its first instance is called.

Sorry, the snippet is not as well constructed as it could have been. Hope it helps.

Comments