最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Dynamically creating polymer element inside another custom tag - Stack Overflow

programmeradmin1浏览0评论

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?"

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?"

Share Improve this question edited Jun 30, 2015 at 3:41 Nazerke asked Jun 29, 2015 at 11:43 NazerkeNazerke 2,0987 gold badges37 silver badges59 bronze badges 2
  • What do you do in the ready callback ? if you want to wait with rendering until the element is added then use the attached callback – Ümit Commented Jun 29, 2015 at 14:51
  • Even if I move everything on ready to on attached, I still have problem of local dom getting rendered immediately. The elements in local dom need attributes in order to render correctly, but because attributes are added after the createElement I can't control it from getting rendered. As I said in the question,the problem is it's not waiting until it is actually appended, but gets rendered just after createElement without waiting for attributes – Nazerke Commented Jun 30, 2015 at 2:42
Add a comment  | 

3 Answers 3

Reset to default 11

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.

You should not use setAttribute but you should set the corresponding property directly.

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

You can use dom api provided by polymer team.

Polymer.dom(parent).appendChild(polymerChild)
发布评论

评论列表(0)

  1. 暂无评论