ajax 完成之前的聚合物渲染元素

polymer render elements before ajax complete

那些日子我在玩聚合物,只是为了测试一些关于AJAX调用等的可能性

并且由于聚合物的性质,由于 DOM/AJAX 竞争条件,我面临一些奇怪的行为。

事实上,我有一个自定义元素,它使用 ajax 调用来检索针对远程服务的信息 (JSON)。

组件如下:

组件模板partners.html

<link rel="stylesheet" href="partners.css" />
<dom-module id="playground-partners">

<template>
    <template is="dom-repeat" items="{{partners}}">
        <section class="partner">
            <img src="{{item.logo}}" alt="partners logo placeholder"/>
            <section class="punshline">{{item.punshline}}</section>
        </section>
    </template>
</template>
<script async type="text/javascript" src="partners.js"></script>

这里是组件函数partners.js

Polymer({
    is: "playground-partners",

    properties: {
        citizenship: {
            type: String
        }
    },

    attached: function(){
        $.ajax({
            context: this,
            url: "http://api.randomuser.me/?results=4&nat="+this.citizenship,
            dataType: 'json',
            success: function(data){
                this.partners = [];
                for (var i = 0, len = data.results.length; i < len; i++) {
                    this.partners.push({
                        logo: data.results[i].user.picture.thumbnail,
                        punshline: data.results[i].user.name.first + " " + data.results[i].user.name.last
                    });
                    console.log(data.results[i].user.name.first);
                    console.log(this.partners[i]);
                }
                console.log(this.partners.length);
            }
        });
    }
});

我不知道为什么,但如果我只使用 1 个结果元素,该元素会在收到响应后立即正确呈现和刷新,但是如果我收到两个或更多对象,它会使用正确数量的模板(这表明它发现 partners 数组具有预期的元素,这由控制台输出确认)。

我不确定如何请求对聚合物进行 DOM 元素刷新。 如果有人能帮助我,那就太好了。

您可以在此处获得 UI:playground UI

您的元素只有 属性 citizenship 但您绑定了合作伙伴。如果你想数据绑定,你必须创建适当的属性。为了让 Polymer 注意到 属性 值的变化,您还需要使用 Polymer API 来更新 this.set()this.notifyPath()、...

等值

为什么要使用 JQuery 来做这个?您应该使用 iron-ajax 元素来执行 ajax 的调用。 Here 您可以找到有关它的文档。
无论如何,我认为你必须异步调用 ajax,如下所示:

attached: function(){
   this.async(function(){
   //ajax call here
   },someTimeIfNeeded);
}

所以,当你得到ajax调用的应答时,你应该使用this.set('pathOfObject', value)来通知数组或对象的变化。

编辑

使用你的元素,我认为你必须做如下:

Polymer({
    is: "playground-partners",

    properties: {
        citizenship: {
            type: String
        },
        partners:{
            type: Array,
            value: function(){return [];}
        },
    },

    attached: function(){
      this.async(function(){  
        $.ajax({
            context: this,
            url: "http://api.randomuser.me/?results=4&nat="+this.citizenship,
            dataType: 'json',
            success: function(data){
                this.set("partners", data.results);
                /* I think that your object should be something like this
                  data:[{logo:"logoUrl", pushLineData:"pushLineData"},
                        {logo:"logoUrl2", pushLineData:"pushLineData2"}
                       ]
               */
            }
        });
      }); 
    },
});

好的,非常感谢 Flavio 和 Günter!

我终于明白了,但我要稍微调整一下你的信息,因为我正在处理一个大的结果集,而不仅仅是一个对象。

有关信息,这里是相关代码部分:

attached: function(){
        this.async( function(){
            $.ajax({
                context: this,
                url: this.url+this.citizenship,
                dataType: 'json',
                success: function(data){
                    sanitizedData = []
                    for (var i = 0, len = data.results.length; i < len; i++) {
                        sanitizedData.push({
                            logo: data.results[i].user.picture.thumbnail,
                            punshline: data.results[i].user.name.first + " " + data.results[i].user.name.last
                        });
                        console.log(sanitizedData);
                    }
                    this.set("partners", sanitizedData);
                }
            });
        });
    }
});

如您所见,我必须使用中间数组才能将整个 for 循环结果插入空的合作伙伴数组。

如果没有这个技巧,只会设置一个对象。

我不太明白的是为什么当我使用这段代码时:

Polymer({
    is: "playground-partners",

    properties: {
        url: {
            type: String
        },
        citizenship: {
            type: String
        }
    },

    attached: function(){
        console.log(this.partners);
        this.async( function(){
            $.ajax({
                context: this,
                url: this.url+this.citizenship,
                dataType: 'json',
                success: function(data){
                    this.partners = []
                    for (var i = 0, len = data.results.length; i < len; i++) {
                        this.partners.push({
                            logo: data.results[i].user.picture.thumbnail,
                            punshline: data.results[i].user.name.first + " " + data.results[i].user.name.last
                        });
                    }
                }
            });
        });
    }
});

Polymer 创建正确数量的子节点但为空。 如果它创建节点,它应该能够获得所需的信息,如果它们是在 push() 调用期间由循环提供的。

这是结果页面:

再次感谢您!