美文网首页iOS学习小集程序员今日看点
使用 MVVM 架构时页面跳转逻辑写在哪儿?

使用 MVVM 架构时页面跳转逻辑写在哪儿?

作者: Sheepy | 来源:发表于2016-11-06 03:14 被阅读3088次

之前我一直在 ViewModel 中处理页面跳转逻辑,VC 直接拿到目标页面进行 push/present。前些天 Code Review 时,同事指出理论上 ViewModel 里不应该出现跟 UIKit 相关的东西。

我觉得很有道理,但我也不赞成把页面跳转逻辑写到 VC 里,我认为在 MVVM 中 VC 中充当了一个 ContainerView 的角色,管理 View 的生命周期,做一些依赖注入之类的事情辅助 View 和 ViewModel 的绑定,它是 View 层的。页面跳转中只有 push/present 这一步是 View 层的,其他诸如通过一些逻辑判断该跳转到哪个页面、跳转之前需要做什么操作之类的代码不该放在 View 层。

但 ViewModel 中出现 UIKit 对象这一点也确实让人难受,于是我用我蹩脚的英语询问了 Rx 社区的外国友人,但结果并不尽如人意:

RxCommunity1.png RxCommunity2.png

他们向我推荐了一篇文章和一个库,虽然并不是我想要的,但还是很感谢他们的热心帮助。第二天我自己写了一个 Router:

typealias Completion = () -> Void

enum PageMap {
    case DemoPage1
    case DemoPage2(String)

    var vc: UIViewController {
        switch self {
        case .DemoPage:
            return DemoController1()
        case .DemoPage2(let title):
            return DemoController2(title: title)
        }
    }
}

enum Router {
    case Push(PageMap)
    case Present(PageMap)

    func go(form vc: UIViewController,
                 animated: Bool = true,
                 completion: Completion? = nil) {

        switch self {
        case .Push(let map):
            vc.navigationController?.pushViewController(map.vc, animated: animated)
        case .Present(let map):
            vc.presentViewController(map.vc, animated: animated, completion: completion)
        }
    }
}

有了这个 Router,ViewModel 就可以提供 Driver<Router>,只要在 VC 里订阅它就好。

果然没有什么问题是加一层抽象不能解决的,科科。

相关文章

网友评论

  • 5da7528ddbb9:有demo吗?
    csqingyang:你可以看看 雷纯峰的 MVVMReactiveCocoa 这个项目. 博主对 MVVM 和 Rx 系列的理解也是有偏差的. MVVM 不使用 RAC/Rx 也是可以实现的, 使用 RAC/Rx 只是更好的实现视图和数据的双向绑定而已@Sheepy
  • AllenYukin:现在公司架构是mvc代码逻辑清晰可见,如果vc囊肿也会抽离封装减负,不懂mvvm对于开发,和代码方面真的可以算是优化么 请大神告知。mvvm就肯定要配置rac使用。
    Sheepy:@乄丶呵小北 我觉得交互比较频繁,业务场景复杂的项目比较适合 MVVM。因为只要绑定了 V 跟 VM 之后就不需要去关心 V 的变化,只要关注数据变化即可。
  • 6e62803aebc1: 意义在哪里...
  • SaiWu:一句话,写在VC
  • 94de8b6897a4:学习了。
  • alston_tsao:你好,在下最近也在思考這問題:我看見國外一些博客分享MVVM,也提出了相同的問題
    (https://medium.com/@red010182/thanks-for-sharing-i-want-to-know-more-about-user-interactions-in-mvvm-pattern-ac9175297600#.e1159k5p3)
    經過簡單的討論後,目前就我的認知是,MVVM的best practice是ViewModel不處裡UI問題,它反而是View跟VC的橋樑,在View跟VC之間反覆傳遞UI responses。我認為這其實是一件非常困擾的事情,需要寫很多“橋樑代碼”。

    舉個例子好了,如果你有一個UIButton,點擊之後需要彈出UIAlert,使用者點擊不同選項,再回到VM做相對應的處理。這麼一個簡單的場景,VM需要兩次proxy,一次從UIButton到VC,一次從VC回到VM。我有時候在想,這樣真的有比較好嗎?如果有大量的UI元件,大量的使用者操作,對應到許許多多不同的邏輯處理,這豈不是累死人?

    所以我一直遲遲無法完全切換至MVVM。我一直想知道,真正使用MVVM的人,究竟是如何處理這樣的UI的各種反饋?

    謝謝
    Sheepy:@alston_tsao 我认为 VM 并不是 View 跟 VC 的桥梁,VM 跟 View(VC)是绑定的关系。一般意义上的 MVVM 是不需要 VC 的,只是在 Cocoa 框架下,VC 天生承担了很多职责,我倾向于将其看作一个功能比较多的 View。你说的“桥梁代码”是存在的,所以我觉得 iOS 中要使用 MVVM 几乎必须依赖 RxSwift/RAC,不然光 View 跟 VM 的绑定就要写很多代码。我使用了 RxSwift,对于你举的例子来说,Button 的点击事件应该提前跟 VM 绑定好,VM 中监听到点击事件后处理逻辑,然后提供一个对应的 Driver<Router>,用来输出处理后的结果,然后 VC 监听这个 Drive<Router>,进行 Alert。

本文标题:使用 MVVM 架构时页面跳转逻辑写在哪儿?

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