在从承诺中获得的聚合物中设置数据绑定值

Setting the data-binding value in polymer that was obtained from a promise

我正在尝试从服务器获取 JSON 格式的时间表数据,并使用它来使用 dom-repeat 呈现时间表。

如果我对 JSON 进行硬编码,代码工作正常,但如果我使用 fetch 设置它,它就不起作用。

<link rel="import" href="../bower_components/polymer/polymer.html">

<dom-module id="xl-schedule">
<template>

<h1> Excel Schedule </h1>

<template is="dom-repeat" items="{{schedule}}">
    <div># <span>{{index}}</span></div>
    <div>Event name: <span>{{item.name}}</span></div>
    <div>Date: <span>{{item.date}}</span></div>
</template>

<script>
Polymer({
  is: 'xl-schedule',
  ready: function() {

    // this.schedule = 
    // [
    //   {
    //     "name": "Event1",
    //     "date": "5/10/2016"
    //   },

    //   {
    //     "name": "Event2",
    //     "date": "5/10/2016"
    //   },

    //   {
    //     "name": "Event3",
    //     "date": "5/10/2016"
    //   }
    // ];

    fetch('resources/schedule.json').
    then(function (response) {
        return response.json();
    }).
    then(function (response) {
      this.schedule = response;
      console.log("response",JSON.stringify(response));
    })
    .catch(function(err) {
      console.log("err",err);
    });

  }

});

正如@Alan 所指出的,在您的第二个 then 回调中:

then(function(response) {
  this.schedule = response; // this === window
})

this 没有引用您的 Polymer 对象。回调是在您的 Polymer 对象的上下文之外调用的,其中 this 未定义。在非strict mode, that results in this defaulting to the global object, which is the window, so you're actually setting window.schedule. You can verify that with console.log(this) in the callback. MDN provides a good reference on this in regards to function context.

箭头函数(在 ES6 中)没有这个问题,并且 this 将绑定到封闭上下文的 this(Polymer 对象):

then(response => this.schedule = response) // this === Polymer obj

假设您正在使用 ES5(或者不想使用 ES6-to-ES5 transpiler),您可以通过向回调传递一个引用来设置 Polymer 对象的 schedule 属性到您的 Polymer 对象,而不是在那里使用 this

Polymer({
  ...
  ready: function() {
    var self = this; // this === Polymer obj
    fetch(...)
      .then(function(response) {
        self.schedule = response;
      });
  }
});

请注意,您可以通过声明 "use strict" 来防止 this 默认为全局对象。这会导致 this 保持 undefined,这会在您无意中分配给 this.schedule 时导致有用的(快速失败)错误 this:

"use strict";
Polymer({
  ...
  ready: function() {
    fetch(...)
      .then(function(response) {
        this.schedule = response; // TypeError: Cannot set property 'schedule' of undefined 
      });
  }
});

这是一个 ES5 演示:plunker