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

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

问题描述

假设我有一个模型 Car,它在 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 vs MVC 无关.这是一个类与结构的问题.(请注意,当模型是结构时,您的评论使用 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.)

视图控制器可以通过 segues 或老式方式"进行转换,方法是直接创建和呈现下一个视图控制器,或者到达它的容器视图控制器(例如导航 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.

从您的编辑中更新:

你问过 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天全站免登陆