小程序之事件總線

一.主要原理git

我把一些會被多個頁面調用的事件放到一個集合裏面,以事件名稱爲key,以事件及其回調函數的數組爲值。大概的形式以下。數組

events={「event_name1」:[[o11,callback11],[o12,callback12]],"event_name2":[[o21,callback21],[o22,callback22]]}app

而後其餘的頁面就能夠從這個池子(集合)裏面經過事件名稱找到對應的事件元素,拿到他的callback函數,進行調用了。函數

二.主要代碼this

事件總線的主要代碼以下:spa

 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。分別分別表明將事件註冊,事件卸載,還有調用事件。code

在on方法中,咱們先檢查當前name所對應的事件是否已存在(經過Array.isArray方法來判斷其是不是數組,由於當callbacks爲[]或者undifined的時候,該方法返回false).若是不存在,則將當前的tuple置爲二維數組中的第一個數組元素。對象

在remove方法中,咱們先經過name獲取到其對應的二維數組callbacks,仍是先經過Array.isArray判斷該二維數組是否存在,若是存在,開始遍歷該二維數組,而且過濾掉第一個元素爲self的數組。(這邊使用到了數組的filter方法,該方法經過回調函數會保留判斷爲true的元素,剔除掉判斷爲false的元素)。而後咱們把過濾後的二維數組從新賦值給events[name]。這樣就實現了事件的卸載。blog

最重要的是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               width: 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         width: 25,
48         height: 25,
49         title: '自提地點',
50         label: {
51           content: '廈門出口加工區\n海景東路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   },
相關文章
相關標籤/搜索