本文来自尚妆Android团队路飞
发表于尚妆github博客,欢迎订阅!接入weex已有几个月,各方面都已慢慢完善。最近遇到一个点,先记录一下。后续会花时间整理一系列weex相关的文章。希望早点完成。
现在有很多页面需要在返回的时候刷新,比如从购物车跳转到详情页加购,再到购物车,这时候应该刷新页面;如果从订单列表页点击付款跳转后进行支付后,返回的时候刷新数据。
首先想到的是weex已经提供的绑定到根元素的viewappear 和 viewdisappear事件。使用方法是绑定到根元素上,
。
- 自定义过component的同学在这里应该不难猜到它是基于fireEvent实现的
- public void onResume() {
- if (wxInstance != null) {
- wxInstance.onActivityResume();
- }
- }
- public void onPause() {
- if (wxInstance != null) {
- wxInstance.onActivityPause();
- }
- }
}}
- _instance.state = state;
- if (state == WeexInstanceAppear) {
- [[WXSDKManager bridgeMgr] fireEvent:_instance.instanceId ref:WX_SDK_ROOT_REF type:@"viewappear" params:nil domChanges:nil];
- }
- else if (state == WeexInstanceDisappear) {
- [[WXSDKManager bridgeMgr] fireEvent:_instance.instanceId ref:WX_SDK_ROOT_REF type:@"viewdisappear" params:nil domChanges:nil];
- }
当触发viewappear事件时,如果不是第一次触发,就当做是返回,根据需求,做刷新请求就可以了。`
- ``
- 到此,viewappear 和 viewdisappear事件是可以满足以上返回刷新的需求的,只要在vue 里判断:
由此想到,如果不仅需要这样的事件,还想给当前页面,从native发其他事件到js,也不基于界面元素,那么该如何办呢?
首先想到的是weex提供的globalEvent,三端都可以发送事件,接收的时候只要注册一下就好了。
- var globalEvent = weex.requireModule('globalEvent');
- globalEvent.addEventListener("geolocation", function (e) {
- console.log("get geolocation")
- });
不过,经过实验会发现,它是全局的,意思是,一个activity/viewcontroller包含多个weex时,只要注册了这个事件,那么就都会收到这个事件。那么一旦我们发送的事件名称出现一样时,就埋了坑,可能出现事件错乱。
这里的解决方案可能会想到规范event name来达到杜绝名称一样的情况,不过这更多是一种治标不治本的办法。
于是就有了本文要介绍的方案,让页面传的事件只有自己页面的js处理。
讲道理,这个功能,要是在weex sdk里实现再好不过了。
说来简单,该方案基于globalEvent,携带instanceId,weex里通过比对instanceId,只有一致的情况下才进行处理。
在渲染weex的fragment/activity的onresume里调用:
resumed:成员变量,默认false
- if (resumed) {
- Map<String,Object> params = new HashMap<>();
- params.put("id", wxInstance.getInstanceId());
- wxInstance.fireGlobalEventCallback("resume", params);
- }
- resumed = true;
在自定义module里增加接口:
- @JSMethod(uiThread = true)
- public void getInstanceId(final JSCallback callback) {
- if (null != callback) {
- JSONObject jsonObject = new JSONObject();
- jsonObject.put("id", mWXSDKInstance.getInstanceId());
- callback.invoke(jsonObject);
- }
- }
iOS:
在渲染weex的viewController里调用:
resumed:成员变量,默认false
- -(void)viewDidAppear:(BOOL)animated{
- [super viewDidAppear:animated];
- if (self.resumed) {
- [_instance fireGlobalEvent:@"resume" params:@{@"id": _instance.instanceId}];
- }
- self.resumed = true;
- }
在自定义module里增加接口:
- -(void)getInstanceId:(WXModuleCallback)callback{
- callback(@{@"id": weexInstance.instanceId});
- }
weex工程里,封装一个函数,其中
是自定义的module
- shopBase
- const shopBase = weex.requireModule('shopBase');
- export default {
- methods: {
- /**
- * config:
- * {
- * event, name of event
- * callback
- * }
- */
- addEventListener(event, callback) {
- if(weex.config.env.platform.toLowerCase() !== 'web') {
- shopBase.getInstanceId((data) => {
- const globalEvent = weex.requireModule('globalEvent');
- const id = data.id;
- globalEvent.addEventListener(event, function (e) {
- if(e.id === id) {
- callback(e);
- }
- });
- })
- }
- },
- },
- };
在需要的页面调用即可,用法同globalEvent:
- addEventListener('resume', function (e) {
- shopModal.toast({ message: e.id });
- });
来源: https://juejin.im/post/59f6d6b46fb9a0450a66a143