如何通过 @Published 变量将两个 ViewModels 关联起来?

huangapple go评论65阅读模式
英文:

How to link two ViewModels together via @Published variable?

问题

class ViewModelA:ObservableObject {
@Published var test = true
}

class ViewModelB:ObservableObject {
@Published var model:Model
init() {
model = load() //加载一些数据
}
func reload() {
//如何在test设置为true时调用此函数?
}
}

英文:

Say I have

class ViewModelA:ObservableObject {
  @Published var test = true
}

class ViewModelB:ObservableObject {
    @Published var model:Model
    init() {
       model = load() //load some data
    }
    func reload() {
       //how to make this func called when test is set to true?
    }
}

答案1

得分: 0

以下是翻译好的内容:

可以让 ViewModelB 订阅 ViewModelA 中的 test 更改的发布通知,并可以检测和获取新发送的值。您需要导入 Combine,请参考下面的代码。这可能会变得相当混乱,但在某些情况下,我需要使用它,并且它可以可靠地工作。您还需要一个上下文,其中 modelB 可以看到 modelA 或者可以将其传递过来。

import SwiftUI
import Combine

class ViewModelA: ObservableObject {
    @Published var test = true
}

class ViewModelB: ObservableObject {
    @Published var model: Model
    
    var modelA = ViewModelA()   // 需要在某处访问 modelA。
    var allCancel: [AnyCancellable] = []
    
    init() {
        // model = load() // 加载一些数据
        let testSink = modelA.$test.sink { newValue in // 订阅发布者
            // 运行您的代码.....
            self.reload(newValue)    // 运行和评估新值的代码
        }
        
        self.allCancel.append(testSink) // 必须保存变量以保持订阅
    }                                 // 可以从数组中删除以停止
    
    func reload(_ newValue: Bool) {
        // 如何使此函数在将 test 设置为 true 时被调用?
    }
}
英文:

It is possible for the ViewModelB to subscribe a sink to the publisher notification of changes of test from ViewModelA and then you can detect and get new values sent. You need to import Combine, See code below. This can get quite messy quite quickly, but there are circumstances where I have needed to use this and it works reliably. You also need a context where modelB can see modelA or can be passed it.

import SwiftUI
import Combine

class ViewModelA:ObservableObject {
@Published var test = true
 }

class ViewModelB:ObservableObject {
@Published var model :Model

var modelA = ViewModelA()   // Need access to modelA somewhere.
var allCancel: [any Cancellable] = []

init() {
  //  model = load() //load some data
	let testSink = modelA.$test.sink { newValue in // Subscribes to the publisher
		// Run your code.....
		self.reload(newValue)		// code to run and evaluate new value
	}
	
	self.allCancel.append(testSink) // Variable must be saved to keep subscription
}									// Can be removed from array to stop

func reload(_ newValue: Bool) {
   //how to make this func called when test is set to true?
}

}

huangapple
  • 本文由 发表于 2023年3月7日 09:48:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/75657358.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定