typescript微信小程序:用方法回调实现页面延迟加载网络数据

typescript微信小程序:用方法回调实现页面延迟加载网络数据_第1张图片

一、实现目标

在微信小程序页面显示地图,地图上有若干个标记点(marker),标记点数据来自网络。
因为网络加载数据有延迟,通常情况下,页面的onLoad代码加载不到这些数据,一个实现思路是通过方法回调,在读取到网络数据的时候,回调页面的setData,以在页面上显示数据信息。
所以,关键点是方法回调的实现。
这个思路的灵感来自于新建的微信小程序的示例代码中读取userInfo的过程。
app.ts中有如下代码:

// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
if (this.userInfoReadyCallback) {
   this.userInfoReadyCallback(res)
  }

index.ts中有如下代码:

onLoad() {
//.............
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
      app.userInfoReadyCallback = res => {
        this.setData({
          userInfo: res.userInfo,
          hasUserInfo: true,
        })
      }
}

具体实现是通过typescript的混合类型接口、可选方法。
在接口定义中有基础方法、属性、可选方法,在接口实现代码中事先不实现可选方法,仅实现基础方法,基础方法实现读取网络数据设置属性的功能,读取后,判断可选方法是否存在,如果存在,则回调可选方法,参数是网络数据;在页面onLoad中加载不到网络数据时,定义可选方法的代码。

二、dataFromNet.ts文件,实现读取地图标记点网络数据。

//地图标记点简单信息的json文件地址
let urlMarkersSimpleJson: string = 'https://xxxxxx.cos.ap-nanjing.myqcloud.com/markers01.json';//简单信息,仅经纬度、名称

//地图标记点简单信息
export class MarkerSimple {
  id: number;//序号
  type: string;//类型
  longitude: number;//经度
  latitude: number;//纬度 
  name: string;//名称
  constructor(id: number, type: string, longitude: number, latitude: number, name: string) {
    this.id = id;
    this.type = type;
    this.longitude = longitude;
    this.latitude = latitude;
    this.name = name;
  }
};
//混合类型的接口定义,简单的地图标记点接口
interface IMarkersSimple {
  (): void;//接口的基础方法
  values: MarkerSimple[];//简单的地图标记点数组,由基础方法从网络请求数据
  valuesCallback?: (values: MarkerSimple[]) => void;//可选的接口的回调方法,
};
//接口实现,仅实现了基础方法代码,事先不实现回调方法
function getMarkersSimple(): IMarkersSimple {
  let func = <IMarkersSimple>function () {
    //网络请求取数据
    wx.request({
      url: urlMarkersSimpleJson,//简单地图标记点json文件的网络地址
      success(res) {
        func.values = <MarkerSimple[]>res.data;
       //读取网络数据后,紧接着判断回调方法是否存在,存在则运行回调方法、传送数据传
       //所以说,这个网络读取数据完成的时间点无法预测
       //如果可选方法存在,说明地图页面onLoad没有加载到数据
        if (func.valuesCallback) { 
          func.valuesCallback(func.values);
        }
      },
      fail(res) {
        console.log(res.errMsg)
      }
    });
  };
  return func;
};
//声明对象变量
export let markersSimple = getMarkersSimple();
//运行对象的基础方法代码,网络请求数据

markersSimple();//  注1

三、ditu.ts地图页面,在地图上显示几个标记点,重点是onLoad代码。

import dataFromNet = require("./dataFromNet");

Page({
  data: {  
  //初始化变量,初始化的数据本身无意义,仅让TypeScript编译器推断变量类型。
  //ditu.wxml页面读取这个数据
    markersSimple: <dataFromNet.MarkerSimple[]>[],
  },
  //页面加载
  onLoad() {
  	//运行markersSimple对象的基础方法,其内部的请求网络数据代码是异步、延迟的。所以无需判断dataFromNet.markersSimple.values是否存在、再赋值给markersSimple,可直接定义和使用回调
    dataFromNet.markersSimple();     

    let thiss = this;//必须暂存this,否则在回调代码中的this不是此this了
    //定义实现回调的代码,用于网络数据请求后回调
    dataFromNet.markersSimple.valuesCallback = function (data: dataFromNet.MarkerSimple[]) {  
    //请求到网络数据后,设置地图标记点简单信息数组,地图上立即显示标记点,不必要显示加载动画,让用户无感延迟
      thiss.setData({                                                         
        markersSimple: data
      })
    }
  },//onLoad
  
  //......

四、提示
dataFromNet.ts中注1 markersSimple();
ditu.ts中注2 dataFromNet.markersSimple();
两者都是运行混合接口对象的基础方法,运行一次即可。
注1代码运行要先于ditu.ts页面加载代码,小伙伴们可以测试。
但到底运行哪一个则有不同的用途。

你可能感兴趣的:(微信小程序,typescript,小程序)