Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically creating polymer element inside another custom tag

A polymer element offices-list needs to be created dynamically inside another polymer element's script as so:

<dom-module id="contacts-tag"> 
    <template>
     <iron-ajax ... on-response = "handleResponse"></iron-ajax>
</template> 
 <script>
    Polymer({
        is: "contacts-tag",  

        handleResponse: function(request){
            var response = request.detail.response;
            this.officesRegions = response.officesRegions;  
            this.officesCities = response.officesCities;    

           var dynamicEl = document.createElement("offices-list");
           dynamicEl.setAttribute("regions", this.officesRegions);
           dynamicEl.setAttribute("cities", this.officesCities);
           document.body.appendChild(dynamicEl); 

        }
       });
</script></dom-module>

However as soon as it reaches "document.createElement("offices-list");" the element inside this new tag starts rendering, and it's on ready method is already called, while I was expecting them to happen after I set attributes. How can I do it?

Edit: Seems that problem is of different nature. I'm setting objects to attributes and "offices-list" tag is not recognizing them, hence isn't able to access it or loop through it. Then, my question will change to, "How to bind objects?"

like image 419
Nazerke Avatar asked Jun 29 '15 11:06

Nazerke


1 Answers

I think the right answer is - it depends on what you are trying to achieve.

If you are looking to imperatively data-bind i.e. you want to dynamically add something like this into the template,

<offices-list offices-regions="{{regions}}"
              offices-cities="{{cities}}">
              </offices-list>

you are out of luck because imperative data-binding is not supported in Polymer 1.0.

If you simply want to pass in parameters (NOT data-bind) into a dynamically-created element, both el.setAttribute() and el.myAttribute = this.myAttribute should work.

Since you are using Polymer, I think you should try to contain DOM manipulations within the framework (inside a Polymer template instance) instead of directly adding to document.body, something like this.

<dom-module id="contacts-tag"> 
  <template>
     <iron-ajax ... on-response="handleResponse"></iron-ajax>
     <div id="insertion_point"></div>
  </template> 
  <script>
    Polymer({
      is: "contacts-tag",
      handleResponse: function(request) {
        ...
        Polymer.dom(this.$.insertion_point).appendChild(dynamicEl);
      }
    });
  </script>
</dom-module>

Lastly, if your intention is to simply display a <contacts-tag> after the ajax request is completed, I think you can achieve this declaratively.

<dom-module id="contacts-tag"> 
  <template>
     <iron-ajax ... on-response="handleResponse"></iron-ajax>

     <template is="dom-if" if="{{_unveilOfficesListWhenReady}}">
       <offices-list offices-regions="{{_regions}}"
                     offices-cities="{{_cities}}">
       </offices-list>
     </template>
  </template> 
  <script>
    Polymer({
      is: "contacts-tag",
      properties: {
        _regions: String,
        _cities: String,
        _unveilOfficesListWhenReady: { type: Boolean, value: false }
      },
      handleResponse: function(request) {
        var response = request.detail.response;
        this._regions = response.officesRegions;  
        this._cities = response.officesCities;
        this._unveilOfficesListWhenReady = true;
      }
    });
  </script>
</dom-module>

No dynamic element needed.

like image 140
zerodevx Avatar answered Sep 19 '22 21:09

zerodevx