一、简述
最近项目组打算引入 weex,并选定了一个页面进行试水。页面很简单,主要是获取数据渲染页面,并可以跳转到指定的页面。跟之前使用 RN 相比,weex 确实要简单很多。从下图中我们可以看到,weex 页面需要跳转到原生页面,并且跳转到哪个页面我们可能并不能写死。也就是说只要原生页面之前项目中写过了,那么理论上来说使用 weex 可以任意调用。那么问题来了,我原来的页面可能只知道名字,我怎么为那个页面传值呢?比如有个页面 orderDetailVC ,跳转时需要传入 orderId,即 orderDetailVC.orderId = @"123";
二、思考
可能最直接的想法就是直接原生给 weex 提供一个方法,让 weex 传入 orderId,然后再 push。但是如果明天我们需要跳转到另一个页面 merchantDetailVC 呢?它需要的不是 orderId 了,可能是一个 merchantId,甚至更多参数。那怎么才能实现任意跳转呢?我的想法是,项目是我写的,需要跳转到哪个类,那么这个类名我肯定是清楚的,并且这个类应该需要什么参数我也是清楚的。只不过我可能不知道怎么用 weex 把它参数传过去而已。如果知道了类名就意味着我知道了这个类,我能找到这个类,那么我就知道这个类有哪些属性了,这个类的所有属性我都能拿到,只不过有些是我需要给它赋值的,有些是不需要处理的。
三、实现
整体的思路是:原生给 weex 提供一个通用的跳转方法。参数是类名和属性字典。
- //控制器相关
- /*
- vcName: 页面名称
- param:页面所需参数(如原来的页面需要传递小区id,工单号等等,字典形式传过去,key 与页面所需参数名称一致即可。
- */
- -(void)pushViewController:(NSString *)vcName param:(NSDictionary *)param;
- /*
- 将APP 当前展示的页面pop
- */
- -(void)popViewController;
- /*
- vcName: 页面名称
- param:页面所需参数(如原来的页面需要传递小区id,工单号等等,字典形式传过去,key 与页面所需参数名称一致即可。
- */
- -(void)presentViewController:(NSString *)vcName param:(NSDictionary *)param finish:(WXModuleCallback)callback;
- /*
- 将APP 当前展示的页面dismiss
- */
- -(void)dismissViewController:(WXModuleCallback)callback;
提供方法后 weex 可以这样调用:
确定了方案之后,剩下唯一的事情就是如何实现给 weex 提供的方法。代码如下:
- -(void)pushViewController:(NSString *)vcName param:(NSDictionary *)param{
- //获取类
- Class vcClass = NSClassFromString(vcName);
- if (vcClass == nil) {
- return;
- }
- BaseViewController *vc = [[vcClass alloc] init];
- vc.hidesBottomBarWhenPushed = YES;
- //属性数量
- unsigned int count = 0;
- //获取属性列表
- objc_property_t *plist = class_copyPropertyList(vcClass, &count);
- for (int i = 0; i<count; i++) {
- //取出属性
- objc_property_t property = plist[i];
- //取出属性名称
- NSString *propertyName = [NSString stringWithUTF8String:property_getName(property)];
- //以这个属性名称作为key ,查看传入的字典里是否有这个属性的value
- if (param[propertyName]) {
- [vc setValue:param[propertyName] forKey:propertyName];
- }
- }
- //释放
- free(plist);
- //获取当前页面控制器
- /*
- 获取当前页面控制器是根据响应链获取的。
- */
- UIViewController *currentVC = [Utils getCurrentVC];
- if ([currentVC isKindOfClass:[UINavigationController class]]) {
- [(UINavigationController *)currentVC pushViewController:vc animated:YES];
- }else{
- [currentVC.navigationController pushViewController:vc animated:YES];
- }
- }
经过小规模自测发现是可以实现需求的。但是由于实现时间不长,可能会有不足之处,请谨慎参考。
来源: http://www.phperz.com/article/17/0722/318499.html