-
-
Notifications
You must be signed in to change notification settings - Fork 22
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can multiple @Queries bind to one single source? #40
Comments
Hello @baoshan, In the Adding Parameters to Queryable Types guide, we see that there are three different ways to create a
import Combine
import SwiftUI
import GRDBQuery
@main
struct QueryTestsApp: App {
var body: some Scene {
WindowGroup {
VStack {
TestView1()
Divider()
TestView2()
}
}
}
}
struct A { var name: String }
struct B { var name: String }
struct RequestA: Queryable {
static var defaultValue: A { A(name: "") }
var search: String
func publisher(in _: EnvironmentValues) -> AnyPublisher<A, Never> {
// Some publisher that publishes various values over time
Timer
.publish(every: 1, on: .main, in: .default)
.autoconnect()
.prepend(Date())
.map { A(name: "\(search) \($0)" )}
.eraseToAnyPublisher()
}
}
struct RequestB: Queryable {
static var defaultValue: B { B(name: "") }
var search: String
func publisher(in _: EnvironmentValues) -> AnyPublisher<B, Never> {
// Some publisher that publishes various values over time
Timer
.publish(every: 1, on: .main, in: .default)
.autoconnect()
.prepend(Date())
.map { B(name: "\(search) \($0)" )}
.eraseToAnyPublisher()
}
}
// MARK: - Version 1
struct TestView1: View {
@State private var search: String = ""
@Query(RequestA(search: ""), in: \.self) private var resultA: A
@Query(RequestB(search: ""), in: \.self) private var resultB: B
var body: some View {
VStack {
TextField("Search", text: $search)
Text("A \(resultA.name)")
Text("B \(resultB.name)")
}
.onChange(of: search) { search in
$resultA.search.wrappedValue = search
$resultB.search.wrappedValue = search
}
}
}
// MARK: - Version 2
struct TestView2: View {
@State private var search: String = ""
var body: some View {
VStack {
TextField("Search", text: $search)
InnerView(search: search)
}
}
private struct InnerView: View {
@Query<RequestA> private var resultA: A
@Query<RequestB> private var resultB: B
init(search: String) {
_resultA = Query(constant: RequestA(search: search), in: \.self)
_resultB = Query(constant: RequestB(search: search), in: \.self)
}
var body: some View {
Text("A \(resultA.name)")
Text("B \(resultB.name)")
}
}
} |
Thanks, Gwendal for the textbook examples! This is too much! I think both are clear and great. I personally prefer the second one because it looks more direct. I wish PS: Is it possible to write this?
|
👍🙂
It should not. The underlying publishers that perform the heavy work are only recreated if the requests actually change (all You can check if the app behaves as you expect by adding a
You mean, without the EDIT: you mean, without the EDIT2: Oh, I see what you mean - I've been both too fast, and slow. You are looking for a shorthand and wondering if some |
I mean a
|
I'm not sure this is possible (maybe I'm wrong). And I'm not sure this is desirable. With the current APIs, it is possible to define All in all, your idea is "left as an exercise" 😉 Maybe you'll find something that's actually cool. I agree that the |
Thanks for sharing your insights! Although I’m closing this thread and I wish more people could benefit from the discussion. Thanks again, Gwendal! |
Thank you for asking an interesting question 😊 Happy GRDBQuery! |
Say there is a
@State private var search: String = ""
plus two@Queries
in a view:These queries need to be synced with the
$search
binding.Besides the (imperative)
.onChange(search) {...}
, is there a better (descriptive) way? Do I need to introduce an extra layer of view to construct the queries?Thank you ❤️
The text was updated successfully, but these errors were encountered: