• 小程序之事件总线


    一.主要原理

    我把一些会被多个页面调用的事件放到一个集合里面,以事件名称为key,以事件及其回调函数的数组为值。大概的形式如下。

    events={“event_name1”:[[o11,callback11],[o12,callback12]],"event_name2":[[o21,callback21],[o22,callback22]]}

    然后其他的页面就可以从这个池子(集合)里面通过事件名称找到对应的事件元素,拿到他的callback函数,进行调用了。

    二.主要代码

    事件总线的主要代码如下:

     1 let events = {};
     2 
     3 const on = function (name, self, callback) {
     4     const tuple = [self, callback];
     5     const callbacks = events[name];
     6     if (Array.isArray(callbacks)) {
     7         callbacks.push(tuple);
     8     }
     9     else {
    10         events[name] = [tuple];
    11     }
    12 }
    13 
    14 const remove = function (name, self) {
    15     const callbacks = events[name];
    16     if (Array.isArray(callbacks)) {
    17         events[name] = callbacks.filter((tuple) => {
    18             return tuple[0] != self;
    19         })
    20     }
    21 }
    22 
    23 const emit = function (name, data) {
    24     const callbacks = events[name];
    25     if (Array.isArray(callbacks)) {
    26         callbacks.map((tuple) => {
    27             const self = tuple[0];
    28             const callback = tuple[1];
    29             callback.call(self, data);
    30         })
    31     }
    32 }
    33 
    34 module.exports = {
    35     on: on,
    36     remove: remove,
    37     emit: emit
    38 }

    首先我们定义了一个events对象,它的结构就是我们上面所说的那样。然后我们写了三个函数,分别是on,remove,emit。分别分别代表将事件注册,事件卸载,还有调用事件。

    在on方法中,我们先检查当前name所对应的事件是否已存在(通过Array.isArray方法来判断其是否是数组,因为当callbacks为[]或者undifined的时候,该方法返回false).如果不存在,则将当前的tuple置为二维数组中的第一个数组元素。

    在remove方法中,我们先通过name获取到其对应的二维数组callbacks,还是先通过Array.isArray判断该二维数组是否存在,如果存在,开始遍历该二维数组,并且过滤掉第一个元素为self的数组。(这边使用到了数组的filter方法,该方法通过回调函数会保留判断为true的元素,剔除掉判断为false的元素)。然后我们把过滤后的二维数组重新赋值给events[name]。这样就实现了事件的卸载。

    最重要的是emit函数,这也是我们做事件总线的主要原因:我们同样通过name来获取二维数组,然后执行该二维数组中的每一个回调函数,此处通过call方法来实现。

    三.使用方法

     1 onShow: function () {
     2     const _this = this;
     3     const key = app.config.amapkey;
     4     const initAmap = new amap.AMapWX({ key: key });
     5     events.on('locationData', this, function (data) {
     6       const origin = data.longitude + ',' + data.latitude;
     7       const destination = app.globalData.destination;
     8       initAmap.getDrivingRoute({
     9         origin: origin,
    10         destination: destination,
    11         success: function (data) {
    12           let points = [];
    13           if (data.paths && data.paths[0] && data.paths[0].steps) {
    14             const steps = data.paths[0].steps;
    15             for (var i = 0; i < steps.length; i++) {
    16               const poLen = steps[i].polyline.split(';');
    17               for (var j = 0; j < poLen.length; j++) {
    18                 points.push({
    19                   longitude: parseFloat(poLen[j].split(',')[0]),
    20                   latitude: parseFloat(poLen[j].split(',')[1])
    21                 })
    22               }
    23             }
    24           }
    25           if (data.paths[0] && data.paths[0].distance) {
    26             _this.setData({
    27               distance: data.paths[0].distance + '米'
    28             });
    29           }
    30           _this.setData({
    31             polyline: [{
    32               points: points,
    33               color: "#0091ff",
    34                1,
    35               dottedLine: true
    36             }]
    37           });
    38         }
    39       })
    40       console.log(destination)
    41 
    42       const markersArray = [{
    43         iconPath: '/resources/image/yipin.png',
    44         id: 'pickUpAddress',
    45         longitude: parseFloat(destination.split(',')[0]),
    46         latitude: parseFloat(destination.split(',')[1]),
    47          25,
    48         height: 25,
    49         title: '自提地点',
    50         label: {
    51           content: '厦门出口加工区
    海景东路18号2楼',
    52           bgColor: '#fff',
    53           padding: '5',
    54           borderRadius: '3'
    55         }
    56       }, {
    57         id: 'myLocation',
    58         longitude: data.longitude,
    59         latitude: data.latitude,
    60       }]
    61       _this.setData({
    62         markersArray, markersArray
    63       })
    64     })
    65   },

    上述代码的第5行,注册了一个事件,名称叫做locationData,并且传入参数this,指代当前页面的page对象,还有一个匿名回调函数。

    接下来看如何调用这个事件

    1   sendLocation: function () {
    2     const _this = this;
    3     wx.getLocation({
    4       type: 'wgs84',
    5       success: function (res) {
    6         events.emit('locationData', res);
    7       }
    8     })
    9   },

    调用emit函数,传入事件名称locationData,并且参数res(对应回调函数的参数data)

    事件销毁方法如下:

    1   onUnload: function () {
    2     const _this = this;
    3     clearInterval(_this.data.locationTimer)
    4     events.remove('locationData', this);
    5   },
  • 相关阅读:
    Android WiFi系统【转】
    TCP服务器端和客户端程序设计【转】
    Ubuntu apt-get update 失败【转】
    AiCloud 2.0 AT开发文档【转】
    【转】简单几步让App Store软件下载快如迅雷 -- 不错!!!
    【转】Mac用户必备!100多款免费实用的苹果Mac软件大搜集
    【转】Mac QQ截图保存在哪里?
    【转】Xcode7.1环境下上架iOS App到AppStore 流程 (Part 三)
    【转】Xcode7.1环境下上架iOS App到AppStore 流程 (Part 二)
    【转】Xcode7.1环境下上架iOS App到AppStore 流程 (Part 一)
  • 原文地址:https://www.cnblogs.com/roy-blog/p/8744087.html
Copyright © 2020-2023  润新知