在需要@Binding 的地方传递@Published(SwiftUI、Combine)
Posted
技术标签:
【中文标题】在需要@Binding 的地方传递@Published(SwiftUI、Combine)【英文标题】:Pass @Published where @Binding is required (SwiftUI, Combine) 【发布时间】:2021-10-15 02:39:15 【问题描述】:ViewModel
类有一个 sourceProperty
正在由 TextField
编辑。该属性是@Published
。我想将它传递给Logic
类,该类有一个带有Binding<String>
的初始化程序。该类将监听sourceProperty
的变化,对它们做出反应并将其输出设置为@Published output
属性。
如何将@Published sourceProperty
作为初始化参数传递给Logic
类?
相关代码:
final class ViewModel
@Published var sourceProperty: String = ""
private var logic: Logic?
init()
self.logic = Logic(data: $sourceProperty)
$logic.output.sink(result in
print("got result: \(result)")
)
final class Logic: ObservableObject
private var bag = Set<AnyCancellable>()
@Published var output: String = ""
@Binding var data: String
init(data: Binding<String>)
self._data = data
$data.sink( newValue in
output = newvalue + "ABCDE"
).store(in: &bag)
到目前为止,我收到以下错误:
无法将“Published.Publisher”类型的值转换为预期值 参数类型“绑定”
目标是使用对象自身属性的更改来触发另一个对象中的方法调用,然后将第二个对象的输出绑定到某个视图。
视图层:
public struct ViewLayer: View
@Binding private var sourceProperty: String
public init(_ placeholder: String,
sourceProperty: Binding<String>,
)
self.placeholder = placeholder
self._sourceProperty = sourceProperty
public var body: some View
TextField(placeholder, text: $sourceProperty)
【问题讨论】:
@Binding
只能在 `Views.如果您的问题也包括视图层,那会更容易提供帮助。
你确定你想要Binding
吗?您正在尝试在其上使用sink
,这是来自Publisher
不,我不确定是否需要binding
。我想要实现的是将两个类连接在一起,这样当 sourceproperty
被写入(通过视图)时,Logic
类将对该更改做出反应并更新它自己的属性。
我同意上面的评论——包括视图层可能很好。听起来您绝对不需要绑定——可能只需将发布者传递给Logic
。但是,我很难理解为什么你也需要嵌套的ObservableObject
s。这似乎很可疑。我明白为什么你的ViewModel
会是ObservableObject
,但不知道为什么Logic
会。而现在,你的代码正好相反。
添加简化视图层为例
【参考方案1】:
如果我正确理解您的问题,您可能正在寻找类似的东西:
final class ViewModel: ObservableObject
@Published var sourceProperty: String = ""
private lazy var logic = Logic(data: $sourceProperty)
private var cancellable: AnyCancellable?
init()
cancellable = logic.$output
.sink result in
print("got result: \(result)")
final class Logic: ObservableObject
@Published private(set) var output: String = ""
init(data: Published<String>.Publisher)
data
.map $0 + "ABCDE"
.assign(to: &$output)
【讨论】:
完美,这看起来达到了我的目标。谢谢!以上是关于在需要@Binding 的地方传递@Published(SwiftUI、Combine)的主要内容,如果未能解决你的问题,请参考以下文章
将 @State 属性的 @Binding 值从容器视图传递到其子视图