我有一个使用MVVM使用SwitUI构建的应用程序,我的父视图包含两个视图A和B,每个视图都有其ViewModel,并且有条件地显示了B。问题是当B 出现和隐藏时,整个父视图都会重新实例化,包括A的ViewModel,这意味着其数据丢失了。
在此示例中,视图A包含一个名为isDataRequested的变量,当视图出现时,该变量设置为true,但是如果切换了ViewB,则isDataRequested将被重置。
父母
struct ParentView: View {
@ObservedObject var viewModel: ParentViewModel
var body: some View {
VStack {
Text("Parent view")
Button(action: {
self.viewModel.showChildB.toggle()
}) {
Text("Toggle ChildB")
}.padding()
ChildAView(viewModel:
ChildAViewModel()
).padding()
if viewModel.showChildB {
Text("ChildB")
}
}
}
}
class ParentViewModel: ObservableObject {
@Published var showChildB = false
}
ChildA
struct ChildAView: View {
@ObservedObject var viewModel: ChildAViewModel
var body: some View {
VStack {
Text("Child A")
HStack {
Text("Is data requested: ")
Text(String(viewModel.isDataRequested)).fontWeight(.black)
}
}.onAppear {
self.viewModel.requestData()
}.background(Color.green)
}
}
class ChildAViewModel: ObservableObject {
@Published var isDataRequested = false
func requestData() {
print("request data A")
isDataRequested = true
}
}
我可以在“ ParentViewModel”中实例化“ ViewModelA”,并且数据不会丢失,但这是正确的方法吗?最佳实践是什么?最重要的是,为什么SwiftUI会重新实例化所有子视图而不是实例化的视图?
答案 0 :(得分:0)
body属性是可计算的属性,这意味着只要更改了内部使用的状态(在您的情况下,还观察到对象),就会重新计算该状态。因此,如果需要数据,可以将子视图中的模型移动到父视图,然后将其传递给子视图,以便在重新计算主体时保留数据。