It has been several months since WEEX was connected, and all aspects have been gradually improved. I came across a point recently. Let me record it. Later, I will spend time sorting out a series of WEEX-related articles. Hope to finish it soon.

demand

There are a lot of pages that need to be refreshed on return, such as when you jump from the cart to the details page to add purchases, and then to the cart. If you click the payment jump from the order list page to make payment, refresh the data when you return.

Viewappear and ViewDisappear events

The first thing that comes to mind is the ViewAppear and ViewDisappear events that weeX already provides to bind to the root element. The method of use is to bind to the root element, and those of you who have customized component should have no trouble guessing that it is implemented based on fireEvent.

  • 1. In Android, you send viewAppear in onResume and ViewAppear in OnPause. Resume and Pause weexInstance are called in their respective places:
public void onResume() {
  if (wxInstance != null) {
    wxInstance.onActivityResume();
  }
}
Copy the code
public void onPause() {
   if (wxInstance != null) {
      wxInstance.onActivityPause();
   }
}
Copy the code
  • 2. In iOS, viewDidAppear events are sent in viewDidAppear and viewDidDisappear events are sent in viewDidAppear. Here you can refer to the WXDemoViewController implementation of the official demo:
- (void)updateInstanceState:(WXState)state { if (_instance && _instance.state ! = state) { _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]; } } } -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self updateInstanceState:WeexInstanceAppear]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [self updateInstanceState:WeexInstanceDisappear]; }Copy the code

Viewappear and ViewDisappear events can satisfy the above requirement of returning a refresh, as long as the vUE judge: when the viewAppear event is triggered, if it is not triggered for the first time, it is regarded as a return, according to the demand, make a refresh request.

Isn’t over

So what if you don’t just need such an event, but want to send other events to the current page from Native to JS that aren’t based on interface elements?

The first thing that comes to mind is weex’s globalEvent, which allows all three terminals to send events and register them when receiving them.

var globalEvent = weex.requireModule('globalEvent');
globalEvent.addEventListener("geolocation", function (e) {
  console.log("get geolocation")
});
Copy the code

If an activity/ viewController contains more than one WEEX, it will receive the event as long as it is registered. So once we send the same event name, we bury the pit, there may be event confusion.

The solution here might be to standardize event names to eliminate the same names, but this is more of a band-aid than a cure.

As a result

This leads to the solution described in this article, in which the events passed by the page are handled only by the JS of the page itself.

In fact, this feature, if in the WEEX SDK implementation of the best.

The principle of

This solution is based on a globalEvent and carries instanceids. Weex only processes the instanceids if they are identical.

Android:

In the onresume of render Weex’s Fragment /activity:

Resumed: A member variable, which defaults to false

if (resumed) {
  Map<String,Object> params = new HashMap<>();
  params.put("id", wxInstance.getInstanceId());
  wxInstance.fireGlobalEventCallback("resume", params);
}
resumed = true;
Copy the code

Add interface to custom 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);
  }
}
Copy the code

iOS:

In the render Weex viewController call:

Resumed: A member variable, which defaults to false

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    if (self.resumed) {
        [_instance fireGlobalEvent:@"resume" params:@{@"id": _instance.instanceId}];
    }
    self.resumed = true;
}
Copy the code

Add interface to custom Module:

-(void)getInstanceId:(WXModuleCallback)callback{
    callback(@{@"id": weexInstance.instanceId});
}
Copy the code

Weex processing:

Weex project, package a function, shopBase is a custom module

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); }}); })}},},};Copy the code

Call it on the desired page, using the same method as globalEvent:

addEventListener('resume', function (e) {
   shopModal.toast({ message: e.id });
});
Copy the code