SwiftUI 和 MVVM - 将数据从子 View 的 ViewModel 传递到父 View 的 ViewModel
SwiftUI and MVVM - passing data from a child View's ViewModel to a parent View's ViewModel
我想知道当一个视图是另一个视图的父视图时如何在 SwiftUI 应用程序中将数据从一个视图模型传递到另一个视图模型,但视图模型没有任何连接。
CarShowView(使用 CarShowViewModel)
当用户单击按钮时显示 sheet CarSearchView(使用 CarSearchViewModel)。
CarSearchViewModel 有一个 allCars 数组,用户可以从中 select 一辆汽车。然后应该将这辆汽车添加到 CarShowViewModel 中的 newCars 数组。
要是我只要抢一辆车就好了。但是用户可能会打开 SearchView,选择一辆车将其添加到 newCars,然后重新打开搜索视图并选择另一辆车添加到 newCars。
我是否需要以某种方式在视图中包含此逻辑?或者有什么方法可以让我使用这些 ViewModel 相互交谈吗?这方面的问题很多,但是我还没找到专门解决这个问题的。
class CarShowViewModel: ObservableObject {
@Published var newCars: [Car]
}
class CarShowView: View {
@ObservedObject var carShowVM = CarShowViewModel()
var body: some View {
// body
}.sheet(isPresented: $showAllCars) {
CarSearchView(carSearchVM: CarSearchViewModel())
}
}
class CarSearchViewModel: ObservableObject {
@Published var chosenCar: Car? = nil
@Published var allCars: [Car]
// repository to grab all cars
var carRepository: CarRepository
func save(car: Car) {
// should save the car I select as chosenCar and close the CarSearch. Somehow I need this to pass the car chosen to CarShowViewModel.
}
}
class CarSearchView {
@ObservedObject var carSearchVM: CarSearchViewModel
}
实现此目的的一种方法是使用传递给第二个视图模型的回调函数,该函数可以在父视图中执行一些代码。类似于:
class CarSearchViewModel: ObservableObject {
@Published var chosenCar: Car? = nil
@Published var allCars: [Car]
var saveCallback: (Car) -> Void
var carRepository: CarRepository
init(carRepository: CarRepository, saveCallback: @escaping (Car) -> Void) {
self.carRepository = carRepository
self.saveCallback = saveCallback
}
func save(car: Car) {
self.saveCallback(car)
}
}
class CarShowViewModel: ObservableObject {
@Published var newCars: [Car] = []
}
struct CarShowView: View {
@ObservedObject var carShowVM = CarShowViewModel()
@State private var showAllCars = false
var body: some View {
Text("Hello, world!")
.sheet(isPresented: $showAllCars) {
CarSearchView(carSearchVM:
CarSearchViewModel(carRepository: CarRepository(), //not sure where this is coming from
saveCallback: { car in
carShowVM.newCars = [car] //or whatever should be here
}))
}
}
}
请注意,我不得不对这里发生的事情进行一些猜测,但这个概念应该是合理的。同样重要的是要注意 SwiftUI View
s 应该是 struct
s,而不是 类——你在代码中错误地标记了它们。
实现此目的的另一种方法是为父视图和子视图提供一个真实来源——基本上,为两者提供一个视图模型。当然,这可能会破坏严格的 MVVM 模式。
还有一些方法可以使用 Combine 和 Publishers 来实现,但我提到的回调方法似乎是最简单的。
我想知道当一个视图是另一个视图的父视图时如何在 SwiftUI 应用程序中将数据从一个视图模型传递到另一个视图模型,但视图模型没有任何连接。
CarShowView(使用 CarShowViewModel) 当用户单击按钮时显示 sheet CarSearchView(使用 CarSearchViewModel)。
CarSearchViewModel 有一个 allCars 数组,用户可以从中 select 一辆汽车。然后应该将这辆汽车添加到 CarShowViewModel 中的 newCars 数组。
要是我只要抢一辆车就好了。但是用户可能会打开 SearchView,选择一辆车将其添加到 newCars,然后重新打开搜索视图并选择另一辆车添加到 newCars。
我是否需要以某种方式在视图中包含此逻辑?或者有什么方法可以让我使用这些 ViewModel 相互交谈吗?这方面的问题很多,但是我还没找到专门解决这个问题的。
class CarShowViewModel: ObservableObject {
@Published var newCars: [Car]
}
class CarShowView: View {
@ObservedObject var carShowVM = CarShowViewModel()
var body: some View {
// body
}.sheet(isPresented: $showAllCars) {
CarSearchView(carSearchVM: CarSearchViewModel())
}
}
class CarSearchViewModel: ObservableObject {
@Published var chosenCar: Car? = nil
@Published var allCars: [Car]
// repository to grab all cars
var carRepository: CarRepository
func save(car: Car) {
// should save the car I select as chosenCar and close the CarSearch. Somehow I need this to pass the car chosen to CarShowViewModel.
}
}
class CarSearchView {
@ObservedObject var carSearchVM: CarSearchViewModel
}
实现此目的的一种方法是使用传递给第二个视图模型的回调函数,该函数可以在父视图中执行一些代码。类似于:
class CarSearchViewModel: ObservableObject {
@Published var chosenCar: Car? = nil
@Published var allCars: [Car]
var saveCallback: (Car) -> Void
var carRepository: CarRepository
init(carRepository: CarRepository, saveCallback: @escaping (Car) -> Void) {
self.carRepository = carRepository
self.saveCallback = saveCallback
}
func save(car: Car) {
self.saveCallback(car)
}
}
class CarShowViewModel: ObservableObject {
@Published var newCars: [Car] = []
}
struct CarShowView: View {
@ObservedObject var carShowVM = CarShowViewModel()
@State private var showAllCars = false
var body: some View {
Text("Hello, world!")
.sheet(isPresented: $showAllCars) {
CarSearchView(carSearchVM:
CarSearchViewModel(carRepository: CarRepository(), //not sure where this is coming from
saveCallback: { car in
carShowVM.newCars = [car] //or whatever should be here
}))
}
}
}
请注意,我不得不对这里发生的事情进行一些猜测,但这个概念应该是合理的。同样重要的是要注意 SwiftUI View
s 应该是 struct
s,而不是 类——你在代码中错误地标记了它们。
实现此目的的另一种方法是为父视图和子视图提供一个真实来源——基本上,为两者提供一个视图模型。当然,这可能会破坏严格的 MVVM 模式。
还有一些方法可以使用 Combine 和 Publishers 来实现,但我提到的回调方法似乎是最简单的。