为什么在SwiftUI中更新父视图时会实例化子ViewModel

时间:2020-05-02 00:48:18

标签: mvvm swiftui

我有一个使用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会重新实例化所有子视图而不是实例化的视图?

1 个答案:

答案 0 :(得分:0)

body属性是可计算的属性,这意味着只要更改了内部使用的状态(在您的情况下,还观察到对象),就会重新计算该状态。因此,如果需要数据,可以将子视图中的模型移动到父视图,然后将其传递给子视图,以便在重新计算主体时保留数据。

Apple Docs