观察到的对象更改时,Swift视图不更新

观察到的对象更改时,Swift视图不更新,swift,firebase,google-cloud-firestore,swiftui,Swift,Firebase,Google Cloud Firestore,Swiftui,我有一些这样的代码: class Data: ObservableObject { @Published var data = dbContent init(){ let db = Firestore.firestore() db.collection("collection").document(userID).addSnapshotListener { //getting data from DB and storing them as objects by appendi

我有一些这样的代码:

class Data: ObservableObject {
 @Published var data = dbContent

 init(){
  let db = Firestore.firestore()
  db.collection("collection").document(userID).addSnapshotListener {
  //getting data from DB and storing them as objects by appending them to data
  }
 }
}
现在的问题是,我可以在2View中删除该项。然后还显示了这一点,我实现了删除数据库中项目的功能。 因此,DB数据会被更改,但在我通过重新访问等方式刷新它之前,它不会显示在3View中


我不知道原因是什么。也许我对
@已发布的
观察对象的理解有误

@State
表示视图拥有数据并管理状态。在子视图中也尝试使用
@ObservedObject
。以下是一个例子:

型号

struct Book:可编码、可识别{
@DocumentID变量id:String?
变量标题:字符串
var作者:String
var numberOfPages:Int
枚举编码键:字符串,编码键{
病例id
案件名称
案例作者
案例编号pages=“页数”
}
}
视图模型

class BooksViewModel:ObserveObject{
@已发布的var books=[Book]()
private var db=Firestore.Firestore()
私有var listenerRegistration:listenerRegistration?
private var cancelables=Set()
init(){
fetchData()
}
脱硝{
注销
}
func unregister(){
如果listenerRegistration!=无{
listenerRegistration?.remove()
}
}
func fetchData(){
注销
listenerRegistration=db.collection(“books”).addSnapshotListener{(querySnapshot,error)在
guard let documents=querySnapshot?.其他文档{
打印(“无文件”)
返回
}
self.books=documents.compactMap{queryDocumentSnapshot->Book?in
返回try?queryDocumentSnapshot.data(as:Book.self)
}
}
}
func deleteBooks(偏移量处:IndexSet){
self.books.remove(原子偏移:偏移)
}
}
视图

导入快捷界面
结构示例视图:视图{
@ObservedObject var viewModel=BooksViewModel()
var body:一些观点{
VStack{
InnerListView1(viewModel:viewModel)
InnerListView2(viewModel:viewModel)
}
}
}
结构InnerListView1:视图{
@观察对象var视图模型:BooksViewModel
var body:一些观点{
名单{
ForEach(viewModel.books){book in
VStack(对齐:。前导){
正文(书名)
.font(.headline)
文本(书的作者)
.font(.subheadline)
文本(\(图书编号页)页)
.font(.subheadline)
}
}
.onDelete{indexSet in
self.viewModel.deleteBooks(at:indexSet)
}
}
}
}
结构InnerListView2:视图{
@观察对象var视图模型:BooksViewModel
var body:一些观点{
列表(viewModel.books){book in
VStack(对齐:。前导){
正文(书名)
.font(.headline)
文本(书的作者)
.font(.subheadline)
文本(\(图书编号页)页)
.font(.subheadline)
}
}
}
}

在试图重现您的问题时,我注意到一件事:如果您使用的是
CodingKeys
(仅当Firestore文档上的属性名称与Swift结构上的属性名称不同时才需要这样做),则需要确保还包括
id
。否则,
id
将为零,这将导致
列表
视图无法区分项目。

@State
表示视图拥有数据并管理状态。在子视图中也尝试使用
@ObservedObject
。以下是一个例子:

型号

struct Book:可编码、可识别{
@DocumentID变量id:String?
变量标题:字符串
var作者:String
var numberOfPages:Int
枚举编码键:字符串,编码键{
病例id
案件名称
案例作者
案例编号pages=“页数”
}
}
视图模型

class BooksViewModel:ObserveObject{
@已发布的var books=[Book]()
private var db=Firestore.Firestore()
私有var listenerRegistration:listenerRegistration?
private var cancelables=Set()
init(){
fetchData()
}
脱硝{
注销
}
func unregister(){
如果listenerRegistration!=无{
listenerRegistration?.remove()
}
}
func fetchData(){
注销
listenerRegistration=db.collection(“books”).addSnapshotListener{(querySnapshot,error)在
guard let documents=querySnapshot?.其他文档{
打印(“无文件”)
返回
}
self.books=documents.compactMap{queryDocumentSnapshot->Book?in
返回try?queryDocumentSnapshot.data(as:Book.self)
}
}
}
func deleteBooks(偏移量处:IndexSet){
self.books.remove(原子偏移:偏移)
}
}
视图

导入快捷界面
结构示例视图:视图{
@ObservedObject var viewModel=BooksViewModel()
var body:一些观点{
VStack{
InnerListView1(viewModel:viewModel)
InnerListView2(viewModel:viewModel)
}
}
}
结构InnerListView1:视图{
@观察对象var视图模型:BooksViewModel
var body:一些观点{
名单{
ForEach(viewModel.books){book in
VStack(对齐:。前导){
正文(书名)
.font(.headline)
文本(书的作者)
.font(.subheadline)
文本(\(图书编号页)页)
.font(.subheadline)
}
}
.onDelete{indexSet in
self.viewModel.deleteBooks(at:indexSet)
}
}
}
}
结构InnerListView2:视图{
@观察对象var视图模型:BooksViewModel
var body:一些观点{
列表(viewModel.books){book in
VStack(对齐:。前导){
正文(书名)
.font(.headline)
文本(书的作者)
.font(.subheadline)
文本(“\(book.numberOfPages)页
struct 1View: View {
 @ObservedObject var myData: Data = Data()

 var body: some View {
  2View(myData: self.myData)
  3View(myData: self.myData)
 }
}
struct 2View: View {
 @State var myData: Data

 var body: some View {
  List(){
   ForEach(data.count){ data in
    Text(data)
   }.onDelete(perform: deleteData) //Deletes the item
  }
 }
}
struct 3View: View {
 @State var myData: Data

 var body: some View {
  List(){
   ForEach(data.count){ data in
    Text(data)
   }.onDelete(perform: deleteData) //Deletes the item
  }
 }
}