【发布时间】:2021-09-30 05:24:12
【问题描述】:
我正在开发一个使用 MVVM 架构的 SwiftUI 应用程序。我有一个问题,我需要将数据从父视图传递到其子视图模型,但我不确定如何将视图中的参数传递到视图模型。
应该拥有 viewModel 的子 View 在这里:
struct InstanceView: View {
@ObservedObject var instance: Instance
@StateObject var viewModel = InstanceViewViewModel(instance: instance)
var body: some View {
...
}
}
这是视图模型:
class InstanceViewViewModel: ObservableObject {
@ObservedObject var instance: Instance
...
}
显然视图不起作用,我收到错误Cannot use instance member 'instance' within property initializer; property initializers run before 'self' is available
如果我尝试在视图中使用init() 为viewModel 赋值:
@ObservedObject var instance: Instance
@StateObject var viewModel: InstanceViewViewModel
init(instance: Instance) {
self.instance = instance
self.viewModel = InstanceViewViewModel(instance: instance)
}
但我收到错误 Cannot assign to property: 'viewModel' is a get-only property。
我读到你应该给 viewModel 属性 (instance) 一个默认值,然后在视图中用.onAppear() 设置它。但是,就我而言,Instance 是一个 Core Data 对象,所以我无法真正创建一个用作默认值。
我还读到我可以在 View 的 init 中使用 _instance = StateObject(wrappedValue: InstanceViewViewModel(instance: instance)),而 swiftUI 将足够聪明,只需初始化一次 StateObject。但是我很确定这是一种不好的做法。
我也不能在StateObject 上使用lazy
那么还有其他方法可以实现吗?解决方案是否可以通过某种方式获取 InstanceView 正在这一行初始化的值:
@StateObject var viewModel = InstanceViewViewModel(instance: instance)
,在 init 之外,所以我不需要像在 init 内部那样引用 self? (这可能是个愚蠢的想法)
或者我应该以不同的方式实现 MVVM?
谢谢!
【问题讨论】:
-
是的,您应该以不同的方式实现 MVVM。 viewModel 是您的事实来源,它应该独立于视图。您尝试使用什么参数对其进行初始化?
-
“但是我很确定这是一个不好的做法。” - 为什么?就像您提到的那样,
StateObject在创建过程中使用了自动关闭,因此它只会创建一次(在我今年夏天的 WWDC 实验室中确认)。使用init或onAppear是 SwiftUI 工程师向我推荐的。 -
在
ObservableObject中存储@ObservedObject没有意义。也许你的意思是@Published? -
这是否回答了您的问题stackoverflow.com/a/62636048/12299030?
标签: swift mvvm swiftui combine observableobject