视图模型和视图如何通信?

问题描述 投票:0回答:3

最近,我正在阅读有关依赖反转的原理,该原理指出高级模块不应依赖于低级模块,它们都应依赖于抽象。

protocol ViewControllerProtocol {
    func saveButtonTapped()
}

struct ViewModel : ViewControllerProtocol{
    func saveButtonTapped() {
        //save data...
        print("forward save request")
    }

     func statusArrived(){
       // inform viewcontroller about updating UI
    }
}


class ViewController: UIViewController {

    private var  vm : ViewControllerProtocol?

    required init(viewmodel : ViewModel){
        self.vm = viewmodel
        super.init(nibName: nil, bundle:nil)
    }

    @IBAction func btnSaveTapped(_ sender: Any) {
        vm?.saveButtonTapped()
    }


}

following dependency inversion principle, i am able to communicate between viewcontroller -> Viewmodel.

my question is, how to communicate in reverse direction ? ie. form view model to view controller ?
i am thinking, by creating another protocol, and viewcontroller implements that protocol....

how to communicate in reverse direction ? ie. form view model to view controller ?



ios swift solid-principles
3个回答
0
投票

您使用闭包返回呼叫。

class ViewController: UIViewController {

    private var  vm : ViewControllerProtocol?

    required init(viewmodel : ViewModel){
        self.vm = viewmodel
        super.init(nibName: nil, bundle:nil)

        self.vm.savedSuccessfully = {
            // do stuff
        }
    }

    @IBAction func btnSaveTapped(_ sender: Any) {
        vm?.saveButtonTapped()
    }


}

struct ViewModel : ViewControllerProtocol{

    var savedSuccesfully: (() -> ())?
    func saveButtonTapped() {
        //save data...
        print("forward save request")
    }

     func statusArrived(){
       // inform viewcontroller about updating UI
       savedSuccesfully?()
    }
}

0
投票

使用委托模式从ViewModel到View进行通讯就可以了,只要ViewModel不拥有View,即没有对View的强引用。

作为替代解决方案,您也可以查看观察者模式,以将消息从ViewModel传递到View。实际上,这就是RxSwift之类的库为您提供的。

[如果您查看了显示依赖关系反转的类图,则对于MVVM,从ViewModel到View的关联始终显示在虚线中,并带有指向View的箭头。这只是意味着ViewModel知道View,但是对它没有任何强引用。


0
投票

添加一个闭包作为完成处理程序

protocol ViewControllerProtocol {
     func saveButtonTapped(completionHandler: ()->())
 }

这是您现在可以使用的方式:-

@IBAction func btnSaveTapped(_ sender: Any) {
     vm?.saveButtonTapped { [weak self] in

         /// From ViewModel -> ViewController
     }
 }

[如果要在该闭包内使用viewController,请不要忘记添加捕获列表以避免保留周期。

© www.soinside.com 2019 - 2024. All rights reserved.