MVVM模式下如何使用ReactiveCocoa响应链式编程<二>

来源:互联网 发布:java开发专业技能 编辑:程序博客网 时间:2024/05/21 06:14

如果你没有看到MVVM模式下如何使用ReactiveCocoa响应链式编程<一>那么请点击上面的连接下面我们继续:

第一篇中我们对viewModel进行了初始化,并在初始化方法中对大Model "CashRedBagModel"进行了初始化。现在已经对viewModel中的                cashModel进行了初始化,其实现在我们已经可以开始写MVVMCheakLuckViewController里面的代码了。但是我们在这之前必须要对一个小Model进行初始化,它将用在MVVMCheakLuckViewController里的UITableView里填充Cell。所以我们接下来看看CashRedBagModel的初始化方法:

.h里面的代码

@interface CashRedBagModel : NSObject

@property (nonatomic,strong) NSString *bless;

@property (nonatomic,strong) NSString *bonusDesc;

@property (nonatomic,strong) NSString *ownerName;
//这个数组里存放着每一个Cell上需要填充的TakeUserModel,在viewController里面会通过点语法获取到这个数组self.viewModel.cashModel.take_userModelArr
@property (nonatomic,strong)NSMutableArray * take_userModelArr;

- (void)initCashsWithDictionary:(NSDictionary *)dic;

@end

.m文件中的代码

- (void)initCashsWithDictionary:(NSDictionary *)dic{
    NSMutableArray *articls = [[NSMutableArray alloc]init];

   //MJExtension字典数组 -> 模型数组
    NSArray *dicArr = [TakeUserModel mj_objectArrayWithKeyValuesArray:[dic objectForKey:@"cashBonusDetailList"]];
    // RAC 风格的数组操作.
    RACSequence * newblogViewModels = [dicArr.rac_sequence
                                       map:^(TakeUserModel * model) {
                                           //通过这个Block会通过初始化CellTakerUserViewModel的方式把Model传过去
                                           CellTakerUserViewModel * vm = [[CellTakerUserViewModel alloc] initWithTakeUserModel:model];

              //return的CellTakerUserViewModel会存放在newblogViewModels.array中
                                           return vm;
                                       }];

  //1.newblogViewModels.array里面放的是CellTakerUserViewModel
    [articls addObjectsFromArray: newblogViewModels.array];

  //2.通过这句代码对.take_userModelArr进行了赋值
    self.take_userModelArr = articls;

  //对其他属性进行赋值
    self.ownerName = [dic objectForKey:@"ownerName"];
    self.bless = [dic objectForKey:@"bless"];
    self.bonusDesc= [dic objectForKey:@"bonusDesc"];
}

UITableView中可以通过[indexPath.row]获取对性的CellTakerUserViewModel进行操作,如下所示:

CellTakerUserViewModel * vm = self.viewModel.cashModel.take_userModelArr[indexPath.row];
    NSArray * arr = vm.dataArr;
    cell.textLabel.text = [NSString stringWithFormat:@"%@",arr[0]];
暂时先不提及ViewControllers里面的内容,暂时简单提及希望可以帮助理解。看官还可以注重看一下RAC 风格的数组操作.然后我要说的是上面第2步:

这句代码是对CellTakerUserViewModel的初始化,并通过初始化的方式把TakeUserModel传入。联系上文可知初始化完成之后会返回一个CellTakerUserViewModel存放在RAC 风格的数组中,下面要看初始化CellTakerUserViewModel的方法实现:

- (instancetype)initWithTakeUserModel: (TakeUserModel *) model

{
        self = [super init];
        if (nil != self) {
            //1.也是RAC的操作,可以理解为一个聚合信号
            RAC(self, userModel) = [RACSignal combineLatest:@[RACObserve(model, take_user),RACObserve(model, money),RACObserve(model,luck_flg)] reduce:^id(NSString * takeuser){
            //2.这一个聚合信号是一个典型的RAC经典例子,希望我这么写会帮助不了解RAC的人更好的理解RAC
                _userModel = [[TakeUserModel alloc]init];
                _userModel.take_user =  model.take_user;
                _userModel.money  =model.money;
                _userModel.luck_flg =model.luck_flg;
                DLog(@"mutableArrmutableArr%@",_userModel.luck_flg);
                return _userModel;
            }];
        }
        return self;
}

RAC的风格数组执行起来像是一个for循环,一一遍历了数组中的每一个对象。其实每次遍历到不同的对象,对象的属性都会发生变化,那么RAC就会监测到。所以有了上面的聚合信号,聚合了TakeUserModel的三个属性,没当这些属性发生变化就会执行reduce里的方法,否则不会执行。执行完成之后返回一个TakeUserModel,并存放在RACSequence * newblogViewModels的array中。也完成了对上一篇标记处的解释。

联系以上步骤,我们在MVVMCheackLuckViewModel中完成了对CashRedBagModel的初始化。在CashRedBagModel中对CellTakerUserViewModel进行了初始化,我们在CellTakerUserViewModel中对TakeUserModel进行了初始化!

在这个过程中我们让MVVMCheakLuckViewController中的下面一段代码中RACObserve(self.viewModel, cashModel)中的viewModel和大Model---->cashModel完成了初始化,所以才让subscribeNext后面Block中的代码成为了可能:
    [RACObserve(self.viewModel, cashModel) subscribeNext:^(id x) {
        [self initHeadView:self.viewModel.cashModel];
        if (self.viewModel.cashModel.take_userModelArr) {
            [self updateTabview];
        }
    }];

我们在MVVMCheakLuckViewController中创建了TabelView只需要实现下面一段代码就完成了第二个界面的创建:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

只粘贴部分代………………

CellTakerUserViewModel * vm = self.viewModel.cashModel.take_userModelArr[indexPath.row];
    TakeUserModel * userModel =vm.userModel;
    cell.textLabel.text = [NSString stringWithFormat:@"%@",userModel.take_user];

}

- (void)initHeadView:(CashRedBagModel *)model{
    UILabel *userLabel = (UILabel *)[self.view viewWithTag:219401];
    UILabel *cashNumberLabel = (UILabel *)[self.view viewWithTag:219402];
    NSString *userStr = [NSString stringWithFormat:@"%@的红包",model.ownerName];
    userLabel .text = userStr;
    cashNumberLabel.text = model.bonusDesc;
    _titleLabel.text = model.bless;
}
你会发现整个controller界面变得简单整洁,而且viewModel,Modle之间也相对比较独立,也可以随意复用。

如果相关相互更多RAC的编程风格,请据需关注。

0 0
原创粉丝点击