我刚刚开始使用SwiftUI,我想使用ViewModels来封装我的逻辑,并将其与视图分离。
现在我刚刚遇到了我的第一个路障,我不知道如何通过这个。
所以到目前为止我的应用程序相当简单。我有两个视图,每个视图都有自己的ViewModel:Parent
和Child
中的一个或多个。Parent
ViewModel保存了一个Item
的列表,这些列表是从后端API中获取的。我想把它传递给Child
及其ViewModel,因为它负责把Item
添加到列表中。
下面是简化的代码:
struct ParentView: View {
@StateObject private var viewModel = ViewModel()
var body: some View {
VStack {
ChildView()
Text("Items: \(viewModel.items.count)")
}
}
}
extension ParentView {
@MainActor class ViewModel: ObservableObject {
@Published var items: [Item] = []
}
}
struct ChildView: View {
@StateObject private var viewModel = ViewModel()
var body: some View {
List {
ForEach(viewModel.items) { item in
Text(item.name)
}
}
.toolbar {
ToolbarItem(placement: .navigationBarTrailing) {
Button {
viewModel.AddItem()
} label: {
Label("Add item", systemImage: "plus")
}
}
}
}
}
extension ChildView {
@MainActor class ViewModel: ObservableObject {
@Published var items: [Item] = []
func AddItem() {
items.append(Item(name: "Test"))
}
}
}
我如何才能使来自父视图模型的项目列表传递到子视图模型,确保只有一个列表,同时确保当该列表更改时两个视图都得到刷新?
谢谢你!
1条答案
按热度按时间gzjq41n41#
你必须在你的
ParentView
中只有一个事实来源,然后你将它传递给子视图。目前你有多个ViewModel
,它们彼此没有关系。在
ChildView
中,将@StateObject private var viewModel = ViewModel()
替换为@ObservedObject var viewModel: ViewModel
,在ParentView
中,使用ChildView(viewModel: viewModel)
将ViewModel
传递给它。同时拆下
extension ChildView ...
并将@MainActor class ViewModel: ObservableObject
从extension ParentView
中取出。请查看此链接,其中提供了一些很好的示例,说明如何使用
ObservableObject
以及如何在应用https://developer.apple.com/documentation/swiftui/managing-model-data-in-your-app中管理数据编辑-1:
下面是我的完整测试示例代码,展示了如何将父视图模型传递给子视图
...ensuring that there is only a single list, while also making sure that both views get refreshed when this list changes