admin管理员组

文章数量:1195157

I have the following polymer element which I have created:

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

I am calling this inside my index.html by doing:

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

I am expecting that for every object returned in the todo array, a <span> will be printed. However, when I run the app, I get the following output in the console:

Uncaught TypeError: Cannot read property 'todos' of undefined

in polymer.html line 1001

I am not sure what is happening here and how to reference the data received back from the ajax response.

I have the following polymer element which I have created:

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

I am calling this inside my index.html by doing:

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

I am expecting that for every object returned in the todo array, a <span> will be printed. However, when I run the app, I get the following output in the console:

Uncaught TypeError: Cannot read property 'todos' of undefined

in polymer.html line 1001

I am not sure what is happening here and how to reference the data received back from the ajax response.

Share Improve this question edited Jun 2, 2015 at 8:55 captainsac 2,4903 gold badges28 silver badges51 bronze badges asked Jun 2, 2015 at 8:49 Ben ThomasBen Thomas 3,2002 gold badges21 silver badges38 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 12

First of all second template that you are using to loop through your data should be a "dom-repeat" and not a "dom-repeater". Secondly you can directly bind the response of iron-ajax to your looping template. Like this,

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

So you are basically binding value of last-response property to your looping template directly.

After banging my head on the wall for a few hours I have managed to solve this. I have created my own element called ajax-service that has a public property called todos which is an Array. In this element, I use the iron-ajax element to do the ajax call.

When the ajax is complete, a function is called and the response is set on the todos property. I have also set the keys reflectToAttribute and notify to true. This means the todos property's value is reflected back to the attribute on the host node and that it is available for two-way binding (see here for more information).

My task-list-app element is as follows:

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

and my ajax-service element:

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

Doing it this way means I am able to edit the data in the on-response function before setting it on the element.

You need to define property before using it in scripts:

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

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

本文标签: javascriptUsing polymer ajax responseStack Overflow