使用具有复杂模型结构的MVVM

时间:2017-10-19 11:39:19

标签: swift core-data mvvm delegates

所以我使用MVVM架构并构建了一个相当复杂的视图,因此我决定将视图拆分为单独的类,然后为每个独立的视图组件使用不同的视图模型。我也使用协调器(基本上是MVVMC),我使用协调器来设置我的视图控制器,然后创建视图模型并将其注入到可在主视图中通过IBOutlet访问的单独视图组件中。

我的问题是我正在使用CoreData并且我试图保存一个具有多个关系的NSManagedObject,但是关系模型仅在连接到我的单独视图的其他视图模型中可用组件。当我从主视图中点击保存按钮时,是否有一种干净的方式可以给我的主视图模型,该模型由我的ViewController拥有来自其他视图模型的关系模型。或者我应该考虑使用委托模式,告诉我的其他视图模型,保存按钮被点击?

1 个答案:

答案 0 :(得分:2)

所以我认为有几种可能性。以下是我尝试管理几乎类似情况的方法,我希望它能帮助你思考。

首先,我为Viewmodels创建协议。例如:

protocol Child1ViewProtocol {
    func getFirstName () -> String
}

protocol Child2ViewProtocol {
    func getLastName () -> String
}

protocol MainViewProtocol {
    func getChildModel1 () -> Child1ViewProtocol
    func getChildModel2 () -> Child2ViewProtocol
    func getLanguage () -> String
    func saveButtonPressed ()
}

然后我创建了我的ViewModel类。这对孩子来说非常简单:

class Child1ViewModel: Child1ViewProtocol {
    var firstName: String?
    init(firstName: String?) {
        self.firstName = firstName
    }
    func getFirstName () -> String {
        return self.firstName ?? ""
    }
}

class Child2ViewModel: Child2ViewProtocol {
    var lastName: String?
    init(lastName: String?) {
        self.lastName = lastName
    }
    func getLastName () -> String {
        return self.lastName ?? ""
    }
}

我的MainViewModel保留了子模型,因此当调用函数saveButtonPressed时我可以访问它们

class MainViewModel: MainViewProtocol {
    var user: User?
    var child1ViewModel: Child1ViewProtocol!
    var child2ViewModel: Child2ViewProtocol!

    init(child1ViewModel: Child1ViewProtocol,
         child2ViewModel: Child2ViewProtocol) {
        self.child1ViewModel = child1ViewModel
        self.child2ViewModel = child2ViewModel
    }
    func getChildModel1 () -> Child1ViewProtocol {
        return self.child1ViewModel
    }

    func getChildModel2 () -> Child2ViewProtocol {
        return self.child2ViewModel
    }

    func getLanguage () -> String {
        return self.user?.language ?? ""
    }

    func saveButtonPressed () {
        self.user?.firstName = self.child1ViewModel.getFirstName()
        self.user?.lastName = self.child2ViewModel.getLastName()
        // And save the user for example
    }
}

这意味着当您在Coordinator中创建MainViewModel时,您还需要创建childViewModel并将它们注入MainViewModel中。这也意味着您不需要在视图中对childViewModel有强引用。