前言
微信小程序越来越火,不少公司都在将原生代码转为微信小程序代码。在开发过程中,由于微信小程序
方法并不支持返回传参,导致一些页面,尤其是从列表页面跳入详情页,用户在详情页改变了状态,返回后无论是否刷新页面,体验都不是很好。在 android 中,我们一般采用
- wx.navigateBack
方法来返回参数,或者直接使用 rxjava 框架或者 eventbus 框架来解决此类问题。
- setresult
业务分析
此类需求大概意思是:A 页面进入 B 页面,B 页面返回并传值给 A。
探索之路
刚开始我想采用一个比较偷懒的方法,利用微信的
缓存在 B 页面存储,返回 A 页面,在
- wx.setStorage
方法里调用
- onshow
读取缓存来实现此功能。但是想想解决方式过于投机取巧,也会给日后维护带来大量隐患。 随后我在网上找到获取前一个
- wx.getStorage
的方法,也可以实现此功能,部分代码如下:
- page
- var pages = getCurrentPages();
- var currPage = pages[pages.length - 1]; //当前页面
- var prevPage = pages[pages.length - 2]; //上一个页面
- //直接调用上一个页面的setData()方法,把数据存到上一个页面中去
- prevPage.setData({
- mdata:1
- })
仔细想了下,代码也不是很安全,因为进 B 页面的入口可能是多个,这样会导致获取的 page 出错。
本来是没招了,突然想到微信小程序支持 js,然后就找了个轻量级的 js 库,而且是观察者模式,是我想要的类型。于是,好戏开始了
onfire.js 介绍
onfire.js 是一个很简单的事件分发的 Javascript 库(仅仅 0.9kb),简洁实用。
github 地址:https://github.com/hustcc/onfire.js [作者不是我]
本地下载地址:http://xiazai.jb51.net/201705/yuanma/onfire.js(jb51.net).rar
可以用于:
实践
整理下思路如下:
A 页面代码:
- var onfire = require("../utils/onfire.js");
- var that;
- var eventObj = onfire.on('key', function () {
- //做具体的事
- });
- Page({
- data: {
- },
- onLoad: function(options) {
- // Do some initialize when page load.
- },
- onReady: function() {
- // Do something when page ready.
- },
- onUnload: function (e) {
- onfire.un('key');
- onfire.un(eventObj2);
- }
- })
直接调用
方法订阅一个名字为 key 的消息,并且无传参。如果需要传参的话,直接在
- onfire.on
里增加参数即可,如
- function
。
- var eventObj = onfire.on('key', function (data)...
需要注意:一定要在
里取消订阅
- onUnload
的消息,并取消绑定
- key
。
- eventObj
B 页面里代码在回调的地方加入
- onfire.fire('key');//key为上文中订阅的消息
- //有参数时
- onfire.fire('key','test');
分析库代码
- function _bind(eventName, callback, is_one, context) {
- if (typeof eventName !== string_str || typeof callback !== function_str) {
- throw new Error('args: '+string_str+', '+function_str+'');
- }
- if (! hasOwnKey(__onfireEvents, eventName)) {
- __onfireEvents[eventName] = {};
- }
- __onfireEvents[eventName][++__cnt] = [callback, is_one, context];
- return [eventName, __cnt];
- }
从代码中可以看出订阅
方法的时候实际调用
- on
方法,该方法,主要是利用一个二维数组来存储订阅的对象。
- _bind
- function _fire_func(eventName, args) {
- if (hasOwnKey(__onfireEvents, eventName)) {
- _each(__onfireEvents[eventName],
- function(key, item) {
- item[0].apply(item[2], args); //执行订阅时的方法
- if (item[1]) delete __onfireEvents[eventName][key]; // 当类型为只订阅一次时,通知后即移除自己。
- });
- }
- }
而
发送消息方法实质调用
- fire
方法,通过名字
- _fire_func
来遍历订阅者,然后通知订阅者。
- key
- function un(event) {
- var eventName, key, r = false,
- type = typeof event;
- if (type === string_str) {
- // 如果存在key值,则移除数组
- if (hasOwnKey(__onfireEvents, event)) {
- delete __onfireEvents[event];
- return true;
- }
- return false;
- } else if (type === 'object') {
- eventName = event[0];
- key = event[1];
- //如果找到这个对象则卸载
- if (hasOwnKey(__onfireEvents, eventName) && hasOwnKey(__onfireEvents[eventName], key)) {
- delete __onfireEvents[eventName][key];
- return true;
- }
- //否则返回false
- return false;
- } else if (type === function_str) {
- //两层循环来判断是否是方法名
- _each(__onfireEvents,
- function(key_1, item_1) {
- _each(item_1,
- function(key_2, item_2) {
- if (item_2[0] === event) {
- delete __onfireEvents[key_1][key_2];
- r = true;
- }
- });
- });
- return r;
- }
- return true;
- }
因为卸载支持按
、对象、方法卸载,所以需要先判断类型,然后按各自规则去解除绑定。
- key
总结
有了这个事件分发库,很多问题游刃而解。好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
来源: http://www.jb51.net/article/113026.htm