ios - SwiftUI:从嵌套视图调用方法
问题描述
我对 SwiftUI 非常熟悉,为了使我的代码更具可读性,我通常将我的视图分解为更小的视图。
假设我有一个 viewModel,从嵌套视图调用我的 viewModel 方法的最佳方法是什么?现在我将我的 ViewModel 作为每个嵌套视图的参数传递,但我发现它不是非常优化和干净......
有没有办法通知 MyMainView HeaderSubview 的按钮被点击了?例如,我可以使用组合吗?
视图模型
class MyViewModel {
func fetchSomeData() {
print("Fetching Some Data")
}
}
主视图
struct MyMainView: View {
var myViewModel = MyViewModel()
var body: some View {
HeaderView(viewModel: myViewModel)
}
}
struct HeaderView: View {
var viewModel: MyViewModel
var body: some View {
HeaderSubview(viewModel: viewModel)
}
}
struct HeaderSubview: View {
var viewModel: MyViewModel
var body: some View {
Button("Search") {
// I want to call my View Model method here
viewModel.fetchSomeData()
}
}
}
解决方案
您可以制作您的类 ObservableObject 并将其作为环境对象注入,因此任何子视图都可以使用它并且主视图将能够观察它。
就像是
class MyViewModel: ObservableObject {
@Published var loading = false
func fetchSomeData() {
loading = true
DispatchQueue.global(qos: .background).async {
print("Fetching Some Data")
// ... long activity here
DispatchQueue.main.async { [weak self] in
self?.loading = false
}
}
}
}
struct MyMainView: View {
@StateObject var myViewModel = MyViewModel()
var body: some View {
HeaderView().environmentObject(myViewModel)
if myViewModel.loading {
Text("Loading...")
}
}
}
struct HeaderView: View {
var body: some View {
HeaderSubview()
}
}
struct HeaderSubview: View {
@EnvironmentObject var viewModel: MyViewModel
var body: some View {
Button("Search") {
// I want to call my View Model method here
viewModel.fetchSomeData()
}
}
}
推荐阅读
- reactjs - 如何使用 TypeScript 以类型安全的方式访问 React 子元素道具?
- python - 如何从 CSV 解析日期时间?
- python - 如何将列附加到字典内的数据框
- plsql - 交互式网格:仅使用不基于表的 PL/SQL 处理
- java - 从 yml 加载属性文件作为 JUNIT 中的工厂 Bean
- mysql - 有没有办法在 HAVING 中包含双重条件?
- ansible - Ansible 使用包含特殊字符的模板失败任务
- wordpress - Fortumo Web SDK 处理
- python - python中的子集问题 - 修复总和到目标的加数
- python - SQLAlchemy `.fetchmany()` 与 `.limit()`