組件化之路(二)組件間交互

前言

有一段時間沒有更新文章了,之前心里默默給自己定下一個小目標(biāo),每周更新一片文章。一方面激勵自己不要懈怠,另一方面也記錄平時開發(fā)中的點(diǎn)滴。后面項(xiàng)目一忙,加班了一段時間也就沒有時間更新了(還是對自己要求不夠高?。? 業(yè)余的時間都花在了王者農(nóng)藥上,(再次譴責(zé)下自己)


IMG_0206.JPG

最近新的項(xiàng)目中使用了混合開發(fā),一直在學(xué)習(xí)react-Native,但是關(guān)于組件化,我也實(shí)踐了一段時間,這里說下我是怎么處理組件間交互的。話不多說,直接開干。

組件間交互的幾種方法。

  • urlRoute 通過注冊url協(xié)議確定跳轉(zhuǎn)路由的方式,(貌似蘑菇街就是使用的這種方式,)
  • action-Target 就是通過RunTime機(jī)制,動態(tài)調(diào)用方法,

一般iOS實(shí)現(xiàn)組件化,都是使用這兩種方式的其中一種,至于哪一種方式更好一點(diǎn),我個人覺得action-Target這種方式更簡潔明了一點(diǎn),不像urlRoute需要配置復(fù)雜的協(xié)議以及路由表。我們項(xiàng)目也是以action-Target為基礎(chǔ)探索組件化的。。

組件間的劃分。

我們是以業(yè)務(wù)來劃分組件的,將單獨(dú)的某一個業(yè)務(wù)拆分成一個組件,其中有一個主組件來負(fù)責(zé),調(diào)度各個組件的數(shù)據(jù)分發(fā),以及處理一些公共的事件。(比如錯誤處理,網(wǎng)絡(luò)監(jiān)聽,登錄狀態(tài)等),整個架構(gòu)如下

  • 其中Base里面有一些基類,BaseController, BaseViewModel 等基本的公共操作
@class  QFBBaseViewModel;
@interface QFBBaseViewController : UIViewController
/**
 *  viewModel
 */
@property (strong, nonatomic, readonly) QFBBaseViewModel *viewModel;

- (instancetype)initWithViewModel:(QFBBaseViewModel *)viewModel;

- (void)bindViewModel;

- (void)popCallBack:(NSDictionary *)infoDic;

@end


在初始化每一個Controller時需要綁定ViewModel

@interface QFBBaseViewModel : NSObject <GlobalStyleProtocol>
/** 用戶當(dāng)前狀態(tài) */
@property (nonatomic, strong, readonly) RACCommand *userStatusCommad;
/** 網(wǎng)絡(luò)狀態(tài)  */
@property (nonatomic, assign) QFNetworkStatus netWorkStatus;
// 接口錯誤信息 在子類設(shè)置某個接口錯誤時顯示的錯誤信息
@property (nonatomic, copy) NSString *errorMessage;
/** 數(shù)據(jù)請求 */
@property (strong, nonatomic, readonly) RACCommand *requestDataCommand;
/** DP層的服務(wù)對象 */
@property (nonatomic, strong, readonly) id<DataDisposeServiceProtocol> services;

- (instancetype)initWithService:(id<DataDisposeServiceProtocol>)service;
- (instancetype)initWithDefaultService;

- (void)initialize;

- (RACSignal *)executeRequestDataSignal:(id)input;

@end

這個ViewModel一個最重要的作用就是來處理統(tǒng)一的網(wǎng)絡(luò)狀態(tài)更新時,處理每一個頁面的數(shù)據(jù)刷新,以及導(dǎo)航欄狀態(tài)的更新。

  • Base組件中有一個最重要的路由表,組件間的通信也就是根據(jù)這個路由表來達(dá)到的。

我的架構(gòu)思路是:路由表是一個Protocol 在這個協(xié)議中配置好跨模塊之間的通信信息傳遞。然后通過action-Target路由器去實(shí)現(xiàn)這個協(xié)議,那么在子組件內(nèi)去實(shí)現(xiàn)這個協(xié)議對應(yīng)的方法。就達(dá)到了跨模塊之間的數(shù)據(jù)傳遞。這樣組件間的依賴關(guān)系就變?yōu)閱雾?xiàng)依賴,也就是所有的子組件只依賴于主組件。

WX20190114-173138@2x.png

如: 在Base模塊的協(xié)議表中定義

@protocol beyondActionProtocol <NSObject>
@optional
/* 跳轉(zhuǎn)報備模塊,新增報備 <ReportClientController.h> */
- (void) pushToAddNewReportControllerWithData:(id)data;
- (void) popAddNewReportController:(id)data;


@end

那么在房源模塊只需要調(diào)用。

 [[MediatorAction sharedInstance] pushToAddNewReportControllerWithData:dic];

而在目標(biāo)模塊 也就是報備模塊只需要遵守協(xié)議并實(shí)現(xiàn)相應(yīng)方法。

//************************   跨模塊跳轉(zhuǎn) ************************/

- (void)pushToAddNewReportControllerWithData:(id)data {
   NSDictionary *dict = data;
   ReportClientViewModel *viewModel = [[ReportClientViewModel alloc]initWithDefaultService];
   viewModel.reporterData = dict;
   id vc = [@"ReportClientController" VKCallClassAllocInitSelectorName:@"initWithViewModel:" error:nil, viewModel];
   UIViewController *currentVC = [self performTarget:nil action:nil];

   if ([vc isKindOfClass:[UIViewController class]]) {
//        UIViewController *vccontoleer = vc;
       QFBaseNavigationController *nav = [[QFBaseNavigationController alloc]initWithRootViewController:vc];
//        vccontoleer.modalPresentationStyle = UIModalPresentationFullScreen;
//        vccontoleer.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
       [currentVC presentViewController:nav animated:YES completion:nil];
//        [currentVC.navigationController pushViewController:vc animated:YES];
   }

}

- (void)popAddNewReportController:(id)data {

   UIViewController *currentVC = [self performTarget:nil action:nil];
   [currentVC.navigationController popViewControllerAnimated:YES];
   // 返回時調(diào)用哪個頁面的回調(diào)方法
//    [@"MyProfileViewController" VKCallClassAllocInitSelectorName:@"popCallBack:" error:nil,data];
}

后記

在實(shí)際開發(fā)中,模塊之間的調(diào)用并沒有這么簡單,還需要處理很多容錯機(jī)制,以及Base組件的瘦身等。我這里只是舉一個簡單的例子來說明我們項(xiàng)目中我對組件間訪問的方法。也希望能幫到需要的人,如果你有更好的方式,也希望(懇請)你能分享你的思路。

關(guān)于組件化,近期可能就不研究了。后期會慢慢更新一些在學(xué)習(xí)React-Navite的一些誤區(qū)和基本知識。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容