You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 07:05:25