SwiftData 关系仅在应用程序重新启动后更新

问题描述 投票:0回答:1

我有 2 个简单模型,具有 1 对多关系。

CarMake
可以有多个
CarModels
,但一个CarModel只能属于一个CarMake。非常简单。

@Model
final class CarModel {
    var name: String
    var make: CarMake
    
    init(name: String, make: CarMake) {
        self.name = name
        self.make = make
    }
}

@Model
final class CarMake {
    var name: String
    @Relationship(inverse: \CarModel.make) var models: [CarModel] = []
    
    init(name: String) {
        self.name = name
    }
}

我创建了一个视图,它将列出所有

CarMakes
,另一个视图将列出
CarModels
的关系属性中的
CarMake
,并且还允许我将新的
CarModel
添加到
CarMake

struct ContentView: View {
    @Environment(\.modelContext) private var modelContext
    @Query private var items: [CarMake]
    
    @State var count: Int = 1

    var body: some View {
        NavigationStack {
            List {
                ForEach(items) { item in
                    NavigationLink(item.name) {
                        CarMakeView(make: item)
                    }
                }
            }
            .toolbar {
                Button {
                    addItem(name: "Car Make \(count)")
                    count += 1
                } label: {
                    Image(systemName: "plus")
                }
            }
        }
    }
    
    private func addItem(name: String) {
        let newItem = CarMake(name: name)
        modelContext.insert(newItem)
    }
}

struct CarMakeView: View {
    @Environment(\.modelContext) private var modelContext
    
    @State var count: Int = 1
    var make: CarMake
    
    var body: some View {
        List {
            ForEach(make.models) { item in
                Text(item.name)
            }
        }
        .toolbar {
            Button {
                addItem(name: "Car Model \(count)")
                count += 1
            } label: {
                Image(systemName: "plus")
            }
        }
    }
    
    private func addItem(name: String) {
        let newItem = CarModel(name: name, make: make)
        modelContext.insert(newItem)
    }
}

将新的

CarModel
对象添加到 modelContext,如
private func addItem(name: String)
中所示,不会导致
make.models
(关系)列表更新。 数据已正确添加到数据库中,因为如果我重新启动应用程序,列表将显示之前应用程序运行中添加的所有
CarModels
。更改屏幕并不重要,直到应用程序重新启动后关系才会更新。 有人可以帮我指出我在这段代码中做错了什么吗?

我尝试简单地添加一个与另一个对象有关系的新对象,然后以一对多关系列出所有对象。我希望一旦更新数据库就可以获得数据。

swiftui swift-data swift-data-relationship
1个回答
0
投票

这是 SwiftData 中的某种错误,因为您没有做任何错误的事情。问题是您的

CarMakeView
具有
make
类型的属性
CarMake
但您不是直接更新该属性而是通过关系,这意味着视图看不到任何依赖项正在更新,并且没有理由自行更新。

这就是错误,因为

make
实际上是在添加新汽车模型时更新的,但不知何故,没有正确观察到关系属性的这种变化。

有一些解决方法

如果关系属性是可选的,我使用的方法是将新的 CarModel 对象附加到

make
属性,因为这样我们就直接更新
make
属性

private func addItem(name: String) {
    let newItem = CarModel(name: name)
    make.models.append(newItem)
}

对于您的情况,我们需要在

CarModel
中将关系属性设为可选,但要使其起作用

@Model
final class CarModel {
    var name: String
    var make: CarMake?

    init(name: String, make: CarMake? = nil) {
        self.name = name
        self.make = make
    }
}

另一个解决方案是出于其他原因进行视图更新,在您的示例中,我只是使用了现有属性

@State var count: Int = 1

并将其添加到文本中的正文中,这将导致视图重绘

var body: some View {
    VStack {
        Text("\(count)")
        List {
            ForEach(make.models) { item in
            //...
© www.soinside.com 2019 - 2024. All rights reserved.