美文网首页
项目MVVM的实际应用

项目MVVM的实际应用

作者: woniu | 来源:发表于2018-12-17 15:00 被阅读57次

    MVVM是一种常见的设计模式,但是在工作中,我最常用的还是MVC的设计模式,MVVM只是在别人的文章中了解过,这一次正好公司项目中MVVM的设计模式,正好拿来分析一波。另外,项目并非全部是MVVM,而是和MVC设计模式掺和在一起的。当然,这并不矛盾。好了,我们就来结合实际项目来分析下MVVM的实现方式吧。

    凡事趁热打铁,过了那个热乎劲想要再重新回到那个状态,难免会付出更多的时间和精力,所以还是少做傻事为妙。

    一、首先我们思考几个问题。

    1、VM页面怎么监控数据的变化?
    2、Controller页面数据的变化怎么让VM随着数据的变化作出相应的调整呢?
    3、因为VM是多个界面公用的,那么VM怎么判断不同页面的请求呢?
    那就让我们来根据这几个疑问来分析吧。

    二、VM页面怎么监控数据的变化?

    用到的技术就是KVO。
    1、首先我们在CourseVM.h类中,添加一个记录当前页面的属性。
    @property (assign, nonatomic) int curPageNo;
    KVO使用这个参数对数据进行监控,一旦刷新完毕,coursLoadOver的布尔值发证改变,触发KVO监控,然后调用代理,最终加载数据完毕。 也就是说,UI界面只管进行UI的处理,VM页面实时通过UI界面的值的改变监控数据的变化,然后再重新返回给UI界面,进行数据的刷新。
    2、设置监控

    1、设置监控参数的路径
    static NSString *const kStrPageNo = @"curPageNo";
    2、对参数路径进行监控
    [self addObserver:self forKeyPath:kStrPageNo options:NSKeyValueObservingOptionNew context:nil];
    3、当监控的参数发生改变的时候,触发监听机制,然后触发代理,在Controller页面的代理中对数据进行处理。
    - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
        
        if ([keyPath isEqualToString:kStrPageNo]) {
            if (self.curPageNo == 1) {
                self.totalNum = 1;
            }
            [self queryCompleteCourseList];
        }else{
            if ([_delegate respondsToSelector:@selector(observeValueForKeyPath:object:)]) {
                [_delegate observeValueForKeyPath:keyPath object:object];
            }
        }
    }
    //注意:- (void)observeValueForKeyPath:(NSString *)keyPath object:(id)object;这个方法是我们写的一个代理,不是KVO的方法,别搞混了。
    
    4、Controller中的代理设置,根据不同的监控,我们调用不同的方法。
    - (void)observeValueForKeyPath:(NSString *)keyPath object:(id)object{
        if ([keyPath isEqualToString:kStrClassLoadOver]) {
            [self.tableView2.mj_header endRefreshing];
            [self.tableView2.mj_footer endRefreshing];
            self.dataList = self.classVM1.dataList;
            for (ClassModel *class in self.dataList) {
                if (class.lessonId.intValue == 0) {
                    self.trialClass = class;
                    break;
                }
            }
            
            if (self.currentTable == self.tableView2) {
                [self showNoData];
                [self.currentTable reloadData];
            }
        }
        else if([keyPath isEqualToString:kStrOpenCurseLoadOver]){
            [self.tableView3.mj_header endRefreshing];
            [self.tableView3.mj_footer endRefreshing];
            self.openCourseList = self.openCourseVM.dataList;
            if (self.currentTable == self.tableView3) {
                [self showNoData];
                [self.currentTable reloadData];
            }
        }
        else if([keyPath isEqualToString:kStrCourseLoadOver]){
            [self.tableView1.mj_header endRefreshing];
            [self.tableView1.mj_footer endRefreshing];
            self.openCourseList = self.openCourseVM.dataList;
            if (self.currentTable == self.tableView1) {
                [self showNoData];
                [self.currentTable reloadData];
            }
        }
    }
    5、我们在Controller中设置初始值。
    self.courseVM.curPageNo = 1;
    这样就会有第一次的刷新,当我们再次上拉刷心的时候。每次
     self.tableView2.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
            self.classVM1.curPageNo = 1;
        }];
    6、在controller刷新的时候,增加监控参数的值,使之发生改变。这样,就会触发VM的KVO监控,然后就调用代理触发Controller中的代理,刷新数据。
    
    

    相关文章

      网友评论

          本文标题:项目MVVM的实际应用

          本文链接:https://www.haomeiwen.com/subject/wjhqkqtx.html