iOS:如何使用MVVM在视图模型之间传递模型? [英] iOS: How to pass a model from view model to view model using MVVM?

查看:120
本文介绍了iOS:如何使用MVVM在视图模型之间传递模型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个汽车模型,该模型在 ViewModel1 中实例化,具有以下初始属性:

Suppose I have a model, Car, that is instantiated in ViewModel1 with the following initial properties:

ViewModel1

let car = Car(make: "McLaren", model: "P1", year: 2015)

然后,我需要在下一个视图控制器中完成汽车的其他信息.遵循MVVM时,在视图控制器之间传递模型的正确方法是什么?

Then I require additional information of the car to be completed in the next view controller. What is the correct way to pass a model between view controllers when following MVVM?

使用MVC,操作很简单,因为视图可以引用模型:

Using MVC, it is simple to do since the view can have reference to the model:

vc2.car = car

下面是对该问题的伪尝试,但是我给人的印象是视图模型应该是私有的,并且只能由单个视图控制器访问.因此,以下尝试对我来说似乎是错误的.

Below is a pseudo attempt at the problem, however I am under the impression that a view model should be private and only accessible to a single view controller. Therefore, the below attempt seems incorrect to me.

ViewController1

fileprivate let viewModel = ViewModel1()

func someMethod() ->  { 
    let car = self.viewModel.car 
    let vc2 = ViewController2()
    vc2.viewModel.car = car
    present(vc2, animated: true, completion: nil)
}

ViewController2

let viewModel = ViewModel2()

func anotherMethod() {
    print(self.viewModel.car.make)  //prints "McLaren"

    viewModel.manipulateCar()       //adds additional information to the car object

    print(self.viewModel.car.color) //prints "Black"

    //Pass the finished car to the last view controller to display a summary
    let vc3 = ViewController3()
    vc3.viewModel.car = self.viewModel.car
}

我想知道上面显示的是使用MVVM时做事的一种好方法,或者如果不是,在视图控制器之间通过汽车的最佳方法是什么?

I am wondering if what I have shown above is a fine way of doing things when using MVVM, or if not, what is the best way to pass the car between view controllers?

编辑

这个问题与Class vs Struct无关.上面的MVC示例暗示它将成为一个类(因为它是一个引用),并且将在多个视图控制器之间传递它以完成对象的更多部分.

This question does not have to do with Class vs Struct. The MVC example above implied it is going to be a class (since it is a reference) and it is being passed between multiple view controllers to complete more parts of the object.

这是一个问题,即在遵循MVVM时如何在视图控制器之间传递模型,以及视图模型是否应为视图控制器专用.

It is a question of how to pass models between view controllers when following MVVM and whether view models should be private to the view controller.

对于MVVM,视图控制器不应引用模型,因此不应具有变量var car: Car?.因此,您不应看到:

With MVVM, the view controller should not reference the model, therefore should not have a variable var car: Car?. Therefore, you should not see:

let vc2 = ViewController2()
vc2.car = car

看到这个消息会不正确吗?

let vc2 = ViewController2()
vc2.viewModel.car = car

推荐答案

此问题与RxSwift甚至MVVM与MVC无关.这是一个Class vs Struct问题. (请注意,当模型是结构体时,您的注释使用MVC,因为视图可以引用模型,这很容易做到"是不正确的,因为您不能将引用传递给结构体.)

This question has nothing to do with RxSwift, or even MVVM vs MVC. This is a Class vs Struct question. (Note that your comment "Using MVC, it is simple to do since the view can have reference to the model" is not correct when the model is a struct, because you can't pass references to structs.)

如何解决此问题完全取决于您如何从视图控制器过渡到视图控制器.

How you solve this problem is entirely dependent on how you transition from view controller to view controller.

当视图控制器负责过渡时,每个视图控制器将负责制作下一个视图控制器,而每个视图模型将负责制作下一个视图模型.通过让父"视图模型侦听子"视图模型(通过委托,回调闭包或反应式可观察到的视图)来完成传递回模型.

When view controllers are in charge of the transition, each view controller would be in charge of making the next view controller and each view model would be in charge of making the next view model. Passing models back is done by having the "parent" view model listen to the "child" view model (through either a delegate, callback closure or reactive observable.)

视图控制器可以通过segue或老式方式"进行过渡,方法是直接创建并呈现下一个视图控制器,或者直接到达其容器视图控制器(例如导航VC)并告诉其进行过渡

View controllers can make the transition either through segues or "the old fashioned way" by creating and presenting the next view controller directly, or reaching up to it's container view controller (navigation VC for example) and telling it to make the transition.

过渡的新趋势是让协调器类代替视图控制器来照顾它.使用此想法,协调器可以保存模型,并根据需要创建视图控制器.然后,视图模型与协调器对话,而不是(可能创建并)彼此对话.这样,视图控制器便彼此独立.

A new trend in transitioning is to have a coordinator class take care of it instead of the view controllers. Using this idea, the coordinator holds the model, and creates view controllers as needed. The view models then talk back to the coordinator instead of (possibly creating and) talking to each other. This way, view controllers are independent of each other.

您可以使视图模型使用委托,闭包回调或Rx Observables与协调器进行对话.

You can have the view models talk back to the coordinator using any of delegates, closure callbacks or Rx Observables.

根据您的修改进行更新:

Update from your edit:

您询问拥有let vc2 = ViewController2(); vc2.viewModel.car = car是否不正确.答案是肯定的,那是不正确的,但是很接近.

You asked if it would be incorrect to have let vc2 = ViewController2(); vc2.viewModel.car = car. The answer is yes, that would be incorrect, but close.

如果视图控制器负责转换,那么您会看到的是:

If view controllers are in charge of the transitions, then you would see is this instead:

// in view controller 1
let vc2 = ViewController2()
vc2.viewModel = self.viewModel.viewModel2

如果使用协调器,则会看到类似以下内容的

If you are using coordinators, then you would see something like:

// in coordinator
let vm2 = ViewModel(car: self.car)
let vc2 = ViewController2(viewModel: vm2)

视图模型背后的关键思想不是它是私有的,也不一定是私有的.关键思想是它是视图控制器持有的唯一非视图对象.您可以将其视为模型控制器".

The key idea behind the view model is not that it's private, it doesn't have to be. The key idea is that it is the only non-view object that the view controller holds on to. You can think of it as a "model controller."

这篇关于iOS:如何使用MVVM在视图模型之间传递模型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆