【问题标题】:Pass data from one ViewModel to another in SwiftUI?在 SwiftUI 中将数据从一个 ViewModel 传递到另一个 ViewModel?
【发布时间】:2021-08-25 07:19:35
【问题描述】:

我有一个 ViewModel VM_App 和一个名称列表,另一个 View V_NamesListV_App 内应该显示这些名称。为此,我将列表从VM_App 传递到VM_NamesList,但在编辑名称时视图会被重绘。

VM_App

class VM_App: ObservableObject {
    @Published var names: [String] = [
        "Tobias",
        "Jonathan",
        ""
    ]
}

V_App

struct V_App: View {
    @ObservedObject var vm: VM_App = VM_App()

    var body: some View {
        VStack {
            V_NamesList(
                VM_NamesList(names: $vm.names)
            )
        }
    }
}

VM_NamesList

class VM_NamesList: ObservableObject {
    @Binding var names: [String]
    
    init(names: Binding<[String]>) {
        self._names = names
    }
}

V_NamesList

struct V_NamesList: View {
    @ObservedObject var vm: VM_NamesList
    
    init(_ vm: VM_NamesList) {
        self.vm = vm
    }
    
    var body: some View {
        ForEach(Array(vm.names.enumerated()), id: \.element) { (i, name) in
            TextField("New Player", text: $vm.names[i])
        }
    }
}

【问题讨论】:

  • 在您的视图模型中使用@Published 而不是@Binding

标签: swift mvvm swiftui viewmodel


【解决方案1】:

你能描述一下你想要做什么吗?

如果要传递视图模型,可以在两个视图中使用相同的视图模型:

struct V_NamesList: View {
    @ObservedObject var vm: VM_App

    var body: some View {
        ForEach(Array(vm.names.enumerated()), id: \.element) { (i, name) in
            TextField("New Player", text: $vm.names[i])
        }
    }
}

您可以从父级传递视图模型:

struct V_App: View {
    @StateObject var vm: VM_App = VM_App()

    var body: some View {
        V_NamesList(vm: vm)
    }
}

在创建和存储可观察对象视图模型时需要使用@StateObject。

【讨论】:

  • 我试图用它自己的 ViewModel 将列表逻辑移动到它自己的 View,@StateObject 成功了,谢谢 :)
【解决方案2】:

在 SwiftUI 上,View 会跟踪你的 ObservableObject 是否会改变。因此,如果您不想在数据更改后刷新视图,请不要跟踪 names 更改。

class VM_App: ObservableObject {
    var names: [String] = [
        "Tobias",
        "Jonathan",
        ""
    ]
}

struct V_App: View {
    @ObservedObject var vm: VM_App = VM_App()

    var body: some View {
        VStack {
            V_NamesList(
                VM_NamesList(names: $vm.names)
            )
        }
    }
}

不过,因为您有 @Binding,它会为 VM_App 设置名称,但会默默地为您的 V_App 更改名称。

【讨论】:

    猜你喜欢
    • 2022-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-09
    • 2023-02-11
    相关资源
    最近更新 更多