5.以一个快的初次加载开始

PWA应用应该快速启动快速可使用。我们当前的状况是我们的天气app开启快速,但是还不可用,因为没数据。我们可以通过AJAX请求获取数据,但是这将造成一个额外的请求并且使得我们的初次加载时间变长。因此,我们将在初次加载就提供真实数据。

注入天气预报数据

在本次实验里,我们将在JavaScript中模拟服务器端注入天气预报数据,但是在一个正式的app中,最新的天气预报数据应该在服务器端基于用于的IP地址地理位置来注入。

在下载的代码中已经包含了我们将注入的数据。即我们在之前的步骤中使用的initalWeatherForecast。

区分出初次运行的部分

但是,我们怎么知道,当天气app从缓存中拉出来时,什么时候展示那些可能与将来的加载并不相关的信息?当用户再次使用app时,他们可能不在上次所查看的城市了,因此我们需要加载新的城市的信息,而不是上次他们看过的城市。

对于用户偏好如用户订阅的城市列表,应该使用IndexedDB或者其他快速存储机制被存储在本地。为了尽可能简化这次实验,我们使用localStorage,虽然在正式app中不是很理想的选择因为它是一种块状,异步的存储机制,并且很有可能在一些设备上很慢。

额外内容:使用idb来替换localStorage的应用,你可以查阅localForage作为一个idb的包裹器

首先,让我们添加保存用户偏好所必须的代码。先在你的代码中找到如下TODO注释:

// TODO add saveSelectedCities function here

然后在如下注释下添加如下代码:

// Save list of cities to localStorage.
  app.saveSelectedCities = function() {
    var selectedCities = JSON.stringify(app.selectedCities);
    localStorage.selectedCities = selectedCities;
  };

然后,让我们添加检查用户是否有保存过城市的开始代码,然后渲染他们,或者使用注入的数据。找到如下注释:

 // TODO add startup code here

然后在如下注释下添加如下代码:

/************************************************************************
   *
   * Code required to start the app
   *
   * NOTE: To simplify this codelab, we've used localStorage.
   *   localStorage is a synchronous API and has serious performance
   *   implications. It should not be used in production applications!
   *   Instead, check out IDB (https://www.npmjs.com/package/idb) or
   *   SimpleDB (https://gist.github.com/inexorabletash/c8069c042b734519680c)
   ************************************************************************/

  app.selectedCities = localStorage.selectedCities;
  if (app.selectedCities) {
    app.selectedCities = JSON.parse(app.selectedCities);
    app.selectedCities.forEach(function(city) {
      app.getForecast(city.key, city.label);
    });
  } else {
    /* The user is using the app for the first time, or the user has not
     * saved any cities, so show the user some fake data. A real app in this
     * scenario could guess the user's location via IP lookup and then inject
     * that data into the page.
     */
    app.updateForecastCard(initialWeatherForecast);
    app.selectedCities = [
      {key: initialWeatherForecast.key, label: initialWeatherForecast.label}
    ];
    app.saveSelectedCities();
  }

这些启动代码检查了是否有任何城市被存储在本地存储中。如果有,将解析使用本地存储的数据然后为每个被保存下来的城市展示一个个预报卡片。如果没有,这些启动代码将直接使用伪造的预报数据并存储为默认的城市。

保存被选中的城市

最终,你需要修改“add city”按钮的处理方法来保存选中的城市到本地存储中。

更新你的butAddCity点击处理方法,使其跟如下代码一致:

document.getElementById('butAddCity').addEventListener('click', function() {
    // Add the newly selected city
    var select = document.getElementById('selectCityToAdd');
    var selected = select.options[select.selectedIndex];
    var key = selected.value;
    var label = selected.textContent;
    if (!app.selectedCities) {
      app.selectedCities = [];
    }
    app.getForecast(key, label);
    app.selectedCities.push({key: key, label: label});
    app.saveSelectedCities();
    app.toggleAddDialog(false);
  });

如果之前没有任何城市选中,这些新添加的城市将被app.selectedCities.push()和app.saveSelectedCities()方法调用并将作为app.selectedCities的初始值。

测试一下

  • 当初次运行的时候,你的应用将从initialWeatherForecast立即向用户展示天气预报;
  • 添加一个新城市(通过点击在右上方的 + 图标)并验证是否有两个卡片出现;
  • 刷新浏览器并验证应用是否卡片都加载出来了并且是最新的信息;

results matching ""

    No results matching ""