使用聚合物 ajax 响应

Using polymer ajax response

我创建了以下聚合物元素:

<link rel="import" href="../bower_components/iron-ajax/iron-ajax.html">

<dom-module id="task-list-app">
    <style>
        :host {

        }
    </style>
    <template>
        <iron-ajax auto url="../tasks.json" handle-as="json" on-response="handleResponse"></iron-ajax>
        <template is="dom-repeater" items="{{todos}}">
            <span>hello</span>
        </template>
    </template>
</dom-module>

<script>
    Polymer({
        is: "task-list-app",
        created: function () {
            this.todos = [];
        },

        handleResponse: function (data) {
            this.todos = data.detail.response;
        }
    });
</script>

我在 index.html 中通过以下方式调用它:

<task-list-app></task-list-app>

我希望对于 todo 数组中返回的每个对象,都会打印一个 <span>。但是,当我 运行 应用程序时,我在控制台中得到以下输出:

Uncaught TypeError: Cannot read property 'todos' of undefined

polymer.html line 1001

我不确定这里发生了什么以及如何引用从 ajax 响应中收到的数据。

首先,您用来遍历数据的第二个模板应该是“dom-repeat”而不是“” dom-中继器”。其次,您可以直接将 iron-ajax 的响应绑定到您的循环模板。像这样,

<link rel="import" href="../bower_components/iron-ajax/iron-ajax.html">

<dom-module id="task-list-app">
    <style>
        :host {

        }
    </style>
    <template>
        <iron-ajax auto url="../tasks.json" handle-as="json" last-response="{{ajaxResponse}}"></iron-ajax>
        <template is="dom-repeat" items="[[ajaxResponse.todos]]">
            <span>{{item.todoItem}}</span>
        </template>
    </template>
</dom-module>

<script>
    Polymer({
        is: "task-list-app"
    });
</script>

所以您基本上是将 last-response 属性 的值直接绑定到您的循环模板。

在用头撞墙几个小时后,我设法解决了这个问题。我创建了自己的元素 ajax-service,它有一个 public 属性 叫做 todos,它是一个 Array。在此元素中,我使用 iron-ajax 元素执行 ajax 调用。

当 ajax 完成时,将调用函数并在 todos 属性 上设置响应。我还将键 reflectToAttributenotify 设置为 true。这意味着 todos 属性 的值会反映回主机节点上的属性,并且它可用于双向绑定(有关详细信息,请参阅 here)。

我的task-list-app元素如下:

<link rel="import" href="ajax-service.html">
<link rel="import" href="task-item.html">
<link rel="import" href="tiny-badge.html">

<dom-module id="task-list-app">
    <style>
        :host {

        }
    </style>
    <template>
        <ajax-service todos="{{todos}}"></ajax-service>
        <template is="dom-repeat" items="{{todos}}">
            <task-item task="{{item}}"></task-item>
        </template>
        <div>
            <tiny-badge>[[todos.length]]</tiny-badge> total tasks
        </div>
    </template>
</dom-module>

<script>
    Polymer({
        is: "task-list-app"
    });
</script>

和我的 ajax-service 元素:

<link rel="import" href="../bower_components/iron-ajax/iron-ajax.html">

<dom-module id="ajax-service">
    <style>
        :host {

        }
    </style>
    <template>
        <iron-ajax auto url="../tasks.json" handle-as="json" on-response="tasksLoaded"></iron-ajax>
    </template>
</dom-module>

<script>
    Polymer({
        is: "ajax-service",
        properties: {
            todos: {
                type: Array,
                reflectToAttribute: true,
                notify: true
            }
        },
        attached: function () {
            this.todos = [];
        },
        tasksLoaded: function (data) {
            this.todos = data.detail.response;
        }
    });
</script>

这样做意味着我可以在 on-response 函数中编辑数据,然后再将其设置到元素上。

在脚本中使用前需要先定义 属性:

<script>
  Polymer({
    is: "task-list-app",
    properties: {
      todos: {
        type: Array,
        notify: true
      }
    },

    handleResponse: function (data) {
      this.todos = data.detail.response;
    }
  });
</script>