admin管理员组文章数量:1403229
I have a following synthetic example:
final class MainViewModel: ObservableObject {
@Published var response: String?
func makeSecondaryViewModel() -> SecondaryViewModel {
SecondaryViewModel(response: $response) // Error
}
}
final class SecondaryViewModel: ObservableObject {
@Binding var response: String?
init(response: Binding<String?>) {
self._response = response
}
func performRequest() {
// Make request here
response = "The result of the request"
}
}
I'm getting an error when trying to initialize SecondaryViewModel
with the response
binding:
Cannot convert value of type 'Published<String?>.Publisher' to expected argument type 'Binding<String?>'
I understand the error, so I have 2 questions:
- What's the right way to make a
@Binding
that would target a property on anotherObservableObject
? - What would be the best way to connect these two ViewModels in a delegation-like relationship, maybe my approach is completely wrong?
In case of an external configuration, i.e. if I pass the response
as a binding in a SwiftUI View, I can actually get this idea to work:
SecondaryViewModel(response: $mainViewModel.response)
The problem is that I cannot do this while being inside the `MainViewModel:
SecondaryViewModel(response: $self.mainViewModel.response) // doesn't work
I have a following synthetic example:
final class MainViewModel: ObservableObject {
@Published var response: String?
func makeSecondaryViewModel() -> SecondaryViewModel {
SecondaryViewModel(response: $response) // Error
}
}
final class SecondaryViewModel: ObservableObject {
@Binding var response: String?
init(response: Binding<String?>) {
self._response = response
}
func performRequest() {
// Make request here
response = "The result of the request"
}
}
I'm getting an error when trying to initialize SecondaryViewModel
with the response
binding:
Cannot convert value of type 'Published<String?>.Publisher' to expected argument type 'Binding<String?>'
I understand the error, so I have 2 questions:
- What's the right way to make a
@Binding
that would target a property on anotherObservableObject
? - What would be the best way to connect these two ViewModels in a delegation-like relationship, maybe my approach is completely wrong?
In case of an external configuration, i.e. if I pass the response
as a binding in a SwiftUI View, I can actually get this idea to work:
SecondaryViewModel(response: $mainViewModel.response)
The problem is that I cannot do this while being inside the `MainViewModel:
SecondaryViewModel(response: $self.mainViewModel.response) // doesn't work
Share
Improve this question
edited Mar 21 at 8:04
Richard Topchii
asked Mar 21 at 7:55
Richard TopchiiRichard Topchii
8,2899 gold badges60 silver badges131 bronze badges
6
|
Show 1 more comment
1 Answer
Reset to default 0You can pass @Published
around and use @Binding
to maintain a single source of truth across various Views. However, IMO, I don't think this is the right way to do. I would rather passing ViewModel within Views instead. Something like this:
struct MySecondView: View {
//Or inject via EnvironmentObject if you want
@StateObject private var viewModel: SecondaryViewModel
init(viewModel: SecondaryViewModel) {
self._viewModel = .init(wrappedValue: viewModel)
}
var body: some View {
...
}
}
struct MyMainView: View {
@StateObject private var viewModel = MainViewModel()
var body: some View {
NavigationStack {
NavigationLink("Move") {
MySecondView(viewModel: .init(response: $viewModel.response))
}
}
}
}
本文标签:
版权声明:本文标题:ios - SwiftUI, Combine: pass @Published property as a @Binding to another object (delegation style) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744367615a2602858.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
@Published private(set) var response: String?
. The logic is a function, consider to combine the two functions into one. – CouchDeveloper Commented Mar 21 at 9:20@Binding
is only meaningful in a View, not in aclass
such asfinal class SecondaryViewModel: ObservableObject
, remove it. – workingdog support Ukraine Commented Mar 21 at 9:34