簡體   English   中英

在 MVVM-C 中的 ViewModel 之間傳遞數據

[英]Passing data between ViewModels in MVVM-C

我正在使用帶協調器的 MVVM 來設計應用程序。 我懷疑的一件事是如何在不同的ViewModels之間傳遞數據。 通常前一個 viewModel 只會創建下一個 viewModel 並且只會在prepareforsegue中進行方法依賴注入。 但是,既然我負責所有導航,我該如何實現呢?

Class AppCoordinator : NSObject, Coordinator, UINavigationControllerDelegate {

    var childCoordinators = [Coordinator]()
    var navigationController: UINavigationController
    var dependencyContainer : MainDependencyContainer
    
    func start() {
        let vc = ViewController.instantiate()
        vc.coordinator = self
        vc.viewModel = dependencyContainer.makeMainViewModel()
        navigationController.delegate = self
        navigationController.pushViewController(vc, animated: true)
    }

    func createAccount() {
        let vc = CreateAccountViewController.instantiate()
        vc.coordinator = self
        navigationController.pushViewController(vc, animated: true)
    }

}

我當然可以在MainViewModel中為CreateAccountViewController創建ViewModel ,並將ViewModel作為參數傳遞到createAccount方法中,但這是正確的方法嗎? 這里的單元測試意味着什么?

理想情況下,您不希望兩個 ViewModel 相互交互並將兩個元素分開。

處理它的一種方法是傳遞導航所需的最少數據。

class AppCoordinator : NSObject, Coordinator, UINavigationControllerDelegate {

    var childCoordinators = [Coordinator]()
    var navigationController: UINavigationController
    var dependencyContainer : MainDependencyContainer

    func start() {
        let vc = ViewController.instantiate()
        vc.coordinator = self
        let viewModel = dependencyContainer.makeMainViewModel()

        // for specific events from viewModel, define next navigation
        viewModel.performAction = { [weak self] essentialData in
            guard let strongSelf = self else { return }
            strongSelf.showAccount(essentialData)
        }

        vc.viewModel = viewModel
        navigationController.delegate = self
        navigationController.pushViewController(vc, animated: true)
    }

    // we can go further in our flow if we need to
    func showAccount(_ data: AnyObject) {
        let vc = CreateAccountViewController.instantiate()
        vc.viewModel = CreateAccountViewController(with: data)
        vc.coordinator = self
        navigationController.pushViewController(vc, animated: true)
    }
}

更進一步,您可以為CreateAccountViewController創建一個特定的協調器,它將使用這些數據進行初始化。 start()方法將創建其 ViewController 所需的任何內容。

// we can go further in our flow if we need to
func showAccount(_ data: AnyObject) {
    let coordinator = CreateAccountCoordinator(data: data, navigationController: navigationController)
    coordinator.start()
    childCoordinators.append(coordinator)
}

在最后一個示例中,協調器僅負責構建其視圖並在需要時將基本信息傳遞給下一個協調器。 viewModel 只暴露給它的視圖,最終視圖並不知道這兩者。 在您的情況下,這可能是一個不錯的選擇。

最后,您可以使用協議抽象進行測試,以確保performAction觸發showAccountshowAccount創建一個子協調器,等等。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM