为什么我的SwiftUI列表再次追加所有对象而不是更新现有对象?

时间:2019-11-19 03:22:10

标签: swift google-cloud-firestore swiftui combine swiftui-list

我正在使用.addSnapshotListener从Firestore读取数据并将其解析为自定义模型Thought

对于我的Firestore集合中的每个文档,我将一个新的Thought对象附加到@Published var thoughts上,并在thoughts中遍历List

struct Thought: Identifiable {

    public var id: String?
    public var name: String
    public var thought: String
    public var color: String
}

class Observer: ObservableObject {

    @Published var thoughts = [Thought]()

    init(){

        self.thoughts.removeAll()

        let db = Firestore.firestore()

        db.collection("thoughts")
        .addSnapshotListener { querySnapshot, error in
            guard let documents = querySnapshot?.documents else {
                print("Error fetching documents: \(error!)")
                return
            }

            for document in documents {

                var thoughtModel = Thought(id: "", name: "", thought: "", color: "")

                thoughtModel.name = document.data()["name"] as! String
                thoughtModel.thought = document.data()["thought"] as! String
                thoughtModel.color = document.data()["color"] as! String

                self.thoughts.append(thoughtModel)
            }
        }
    }
}

struct ThoughtsView: View {

    @ObservedObject var observer = Observer()

    var body: some View {
        VStack {
            List {
                ForEach(self.observer.thoughts, id: \.name) { thought in

                    ThoughtCard(color: thought.color,
                                thought: thought.thought,
                                name: thought.name)
                }
            }
        }
    }
}

当我在Firestore集合中进行更改或添加文档时,所有对象都将附加到我的List上,而不是像我期望的那样更新到我的List上。换句话说,如果我在List中有3个项目,并且更改了其中一个Firestore文档中的值,那么我在List中将有6个项目,其中包括原始的3个项目,以及一个重复项原来的3个(修改后的)中的一个。

如何正确更新我的List

1 个答案:

答案 0 :(得分:2)

  

所有对象都被追加到我的列表中,而不是像我期望的那样被更新。

您的期望是正确的,但是...

  

@ObservedObject var observer = Observer()

...您的观察者仅创建一次并保留在ThoughtsView之外,因此,即使在更新时重建视图,也将使用相同的观察对象,所以...

init(){
   self.thoughts.removeAll()

此代码仅被调用一次,因为它在构造函数中,实际上是无用的。但是这部分

  

self.thoughts.append(thoughtModel)

每次更新都会调用

...,因为它位于.addSnapshotListener中。结果,您看到的就是-连续追加。

解决方案。根据代码的逻辑,我假设您的意思是这个容器清理的地方

   self.thoughts.removeAll()
   for document in documents {