英文:
SwiftData query with dynamic properties in a View
问题
我正在尝试找出如何创建一个SwiftUI视图,该视图可以显示来自SwiftData的数据,使用包含传递到视图的变量的查询。我猜想我可能无法使用@Query语法,但是否有人找到了一种可行的方法来做类似这样的事情?
我是否需要放弃@Query,只是创建一个视图模型,该模型实例化自己的ModelContainer和ModelContext?
这段代码显然无法编译,因为@Query引用了startDate和endDate变量,但这正是我想要的。
struct MyView: View {
@Environment(\.modelContext) var modelContext
@Query(FetchDescriptor<Measurement>(predicate: #Predicate<Measurement> {
$0.date >= startDate && $0.date <= endDate }, sortBy: [SortDescriptor(\Measurement.date)])) var measurements: [Measurement]
let startDate: Date = Date.distantPast
let endDate: Date = Date.distantFuture
var body: some View {
Text("Help")
}
}
英文:
I'm trying to figure out how to make a SwiftUI view that displays data from SwiftData using a query that includes variables passed into the view. I'm guessing that I won't be able to use the @Query syntax, but has anyone come up with a workable method to do something like this?
Do I need to abandon the @Query and just create a view model that instantiates it's own ModelContainer and ModelContext?
This code is obviously not compiling because the @Query is referencing the startDate and endDate variables, but this is what I want.
struct MyView: View {
@Environment(\.modelContext) var modelContext
@Query(FetchDescriptor<Measurement>(predicate: #Predicate<Measurement> {
$0.date >= startDate && $0.date <= endDate }, sortBy: [SortDescriptor(\Measurement.date)])) var measurements: [Measurement]
let startDate: Date = Date.distantPast
let endDate: Date = Date.distantFuture
var body: some View {
Text("Help")
}
}
答案1
得分: 2
你不能拥有一个动态查询(还没有),但一个解决方法是将日期(或完整谓词)注入到视图中,然后以这种方式创建查询。
@Query var measurements: [Measurement]
init(startDate: Date, endDate: Date) {
let predicate = #Predicate<Measurement> {
$0.date >= startDate && $0.date <= endDate
}
_measurements = Query(filter: predicate, sort: \.date)
}
英文:
You can't have a dynamic query (not yet) but a workaround is to inject in the dates (or the full predicate) into the view and create the query that way.
@Query var measurements: [Measurement]
init(startDate: Date, endDate: Date) {
let predicate = #Predicate<Measurement> {
$0.date >= startDate && $0.date <= endDate
}
_measurements = Query(filter: predicate, sort: \.date)
}
答案2
得分: 0
我写了一个内部类来显示列表中的筛选记录:
struct DemoListContentView: View {
@Environment(\.modelContext) private var modelContext
@Query(
FetchDescriptor()
) private var items: [Item]
init(endDate: Date) {
let past = Date.distantPast
let predicate = #Predicate<Item> {
($0.creationDate ?? past) <= endDate
}
_items = Query(filter: predicate)
}
var body: some View {
NavigationView {
VStack{
Text("\(items.count)")
List {
ForEach(items) { item in
ItemCell(item: item)
}
}
}
}
}
}
它将在以下地方调用:
import SwiftUI
import SwiftData
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@State var lastFetch = Date()
var body: some View {
DemoListContentView(endDate: lastFetch)
}
}
希望能有所帮助。
英文:
my two cents. I wrote an inner class to show filtered record in list:
struct DemoListContentView: View {
@Environment(\.modelContext) private var modelContext
@Query(
FetchDescriptor()
) private var items: [Item]
init(endDate: Date) {
let past = Date.distantPast
let predicate = #Predicate<Item> {
($0.creationDate ?? past) <= endDate
}
_items = Query(filter: predicate)
}
var body: some View {
NavigationView {
VStack{
Text("\(items.count)")
List {
ForEach(items) { item in
ItemCell(item: item)
}
}
}
}
}
}
it will called in:
import SwiftUI
import SwiftData
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@State var lastFetch = Date()
var body: some View {
ListContentView(endDate: lastFetch)
}
}
Hope can help.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论