2015-06-02 12 views
6

ich folgendes Polymerelement haben, die ich geschaffen habe:Mit Polymer Ajax Antwort

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

ich dies in meinem index.html nenne, indem Sie:

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

ich für jede erwartete ich, dass Objekt, das im Todo-Array zurückgegeben wird, wird <span> gedruckt. Allerdings, wenn ich die App laufen lasse, erhalte ich die folgende Ausgabe in der Konsole:

Uncaught TypeError: Cannot read property 'todos' of undefined

in polymer.html line 1001

Ich bin nicht sicher, was hier und wie geschieht die empfangenen Daten wieder aus der Ajax-Antwort auf Referenz .

Antwort

6

Nachdem ich für ein paar Stunden meinen Kopf an die Wand geschlagen habe, habe ich es geschafft, dies zu lösen. Ich habe mein eigenes Element mit der Bezeichnung ajax-service erstellt, das eine öffentliche Eigenschaft namens todos hat, die eine Array ist. In diesem Element verwende ich das Element iron-ajax, um den Ajax-Aufruf auszuführen.

Wenn der Ajax abgeschlossen ist, wird eine Funktion aufgerufen und die Antwort auf die Eigenschaft todos festgelegt. Ich habe auch die Tasten reflectToAttribute und notify auf true gesetzt. Dies bedeutet, dass der Wert der Eigenschaft todos auf das Attribut auf dem Host-Knoten zurückreflektiert wird und dass er für die bidirektionale Bindung verfügbar ist (weitere Informationen finden Sie unter here).

Mein task-list-app Element ist wie folgt:

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

und mein ajax-service Elemente:

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

tut es auf diese Weise bedeutet, dass ich bin in der Lage, die Daten in der on-response Funktion zu bearbeiten, bevor es Einstellung auf das Element.

+5

Sie möchten wirklich nicht 'reflectToAttribute: true', insbesondere für Array- oder Objektdaten. Es spammt Ihr DOM mit potenziell massivem JSON und wird nicht zum Binden benötigt. –

12

Zunächst einmal zweiten Vorlage, die Sie Schleife durch Ihre Daten verwenden, sollte eine „dom-repeat“ und keine „dom-Repeater“. Zweitens können Sie die Antwort von Eisen-Ajax direkt an Ihre Looping-Vorlage binden. Wie diese

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

Sie sind also grundsätzlich verbindlich Wert von Last-Antwort Eigenschaft auf Ihre Looping-Vorlage direkt.

+0

Vielen Dank für Ihre Antwort, ich habe es jetzt arbeiten bekommen verwaltet. Nehmen wir an, ich musste zuerst die Antwortdaten ändern, wie konnte ich dies mit dem Aufruf von handleResponse erreichen? –

+0

Auch wenn ich ein neues Objekt in dieses Array schieben wollte, wie würde ich das tun? –

5

Sie müssen Eigenschaft definieren, bevor es in Skripten:

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

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