【问题标题】:Why is child ViewModel instantiated when parent view is updated in SwiftUI为什么在 SwiftUI 中更新父视图时会实例化子 ViewModel
【发布时间】:2020-08-16 13:34:57
【问题描述】:

我有一个使用 MVVM 使用 SwitUI 构建的应用程序,我的父视图包含两个视图 A 和 B,每个视图都有其 ViewModel,并且 B 有条件地显示。问题是当 B 出现隐藏整个父视图被重新实例化,包括 A 的 ViewModel,这意味着它的数据丢失了。

这是一个示例,其中视图 A 包含一个名为 isDataRequested 的变量,当视图出现时它被设置为 true,但如果切换视图 B,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 会重新实例化所有子视图而不是更改的子视图?

【问题讨论】:

  • body 是可计算的属性,所以一旦调用里面的一切都是computed。实际上,它只是一个函数。

标签: mvvm swiftui


【解决方案1】:

body 属性是一个可计算的属性,这意味着只要在其中使用的状态(在您的情况下也是观察到的对象)发生更改,它将被重新计算。因此,如果您需要数据,您可以将子视图中的模型移动到父视图并将其传递给子视图,以便在重新计算主体时保留数据。

Apple Docs

【讨论】:

    猜你喜欢
    • 2020-02-02
    • 1970-01-01
    • 1970-01-01
    • 2021-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多