如何通过@Published变量关联两个ViewModel并触发指定方法?
当ViewModelA的test变量设为true时调用ViewModelB的reload()方法的实现方案
下面是几种可行的实现方式:
1. 通过Combine订阅属性变化
利用Combine框架让ViewModelB监听ViewModelA的test属性,当它变为true时自动触发reload()。这种方式适合在ViewModel层完成逻辑解耦的场景。
import Combine class ViewModelA: ObservableObject { @Published var test = true } class ViewModelB: ObservableObject { @Published var model: Model private var cancellables = Set<AnyCancellable>() private let viewModelA: ViewModelA init(viewModelA: ViewModelA) { self.viewModelA = viewModelA self.model = load() // 加载初始数据 // 订阅test的变化,仅在值为true时响应 viewModelA.$test .filter { $0 == true } .sink { [weak self] _ in self?.reload() } .store(in: &cancellables) } func reload() { model = load() // 重新加载数据 } } // 假设的Model和加载方法 struct Model {} func load() -> Model { Model() }
- 用
[weak self]避免循环引用,cancellables用来管理订阅生命周期,防止内存泄漏。 - 通过依赖注入传入ViewModelA,让两个ViewModel的依赖关系更清晰。
2. 在View层监听触发
如果两个ViewModel都在同一个View中实例化,可以直接在View里监听viewModelA.test的变化,满足条件时调用viewModelB.reload()。这种方式无需修改ViewModel内部结构,实现更简单。
struct ContentView: View { @StateObject var viewModelA = ViewModelA() @StateObject var viewModelB = ViewModelB() var body: some View { Text("示例页面") .onChange(of: viewModelA.test) { newValue in if newValue { viewModelB.reload() } } } }
内容的提问来源于stack exchange,提问作者erotsppa
相关产品推荐
相关产品推荐

