【发布时间】:2020-04-13 16:03:13
【问题描述】:
我想知道通过可观察对象清除视图中显示的列表数据的最有效方法是什么?目前,每次我重新加载视图时,数据都会重复(因为我们正在检查查询以获取更新并解析响应)。这不是预期的行为。预期的行为将是仅更新 @Published 属性“如果”数据库指示已收到新通知。
我知道罪魁祸首是 .onAppear 块中的代码 - 我只是不确定在架构上如何解决这个问题。我怎么能在只解析新数据而不是之前解析的数据时使用这个监听器?
我试图清除列表 .onAppear,但导致崩溃表明我试图删除一个部分,而已经有 0 个部分,所以这不起作用。
我考虑过在发送到 Firebase(或使用 firebase 密钥本身)时,可能会为 Message 对象提供静态唯一 ID 以与 Message 对象一起上传。这样我就可以使用一组使用唯一 ID 的字典对象来识别字典中的对象。这可以帮助我避免重复条目。
struct Updates: View {
@ObservedObject var dataController = DataController()
var body: some View {
ZStack {
VStack {
List {
ForEach(self.dataController.messages, id: \.id) { message in
Text(message.message)
}
}
}.onAppear {
self.dataController.query.observe(.childAdded) { snapshot in
let data = JSON(snapshot.value as Any)
if let message = Message.parseFirebaseQuery(dataJSON: data){
self.dataController.messages.append(message)
}
}
}
}
}
}
class DataController: ObservableObject {
@Published var query = ChatPathsAndReferences.refs.databaseMessages.queryLimited(toLast:100).queryOrdered(byChild: "date")
@Published var messages = [Message]()
}
【问题讨论】:
-
我不确定,但我认为这种方法会有问题。使用 Firebase,您无需像 Firebase 那样添加观察者。换句话说,向节点添加 .childAdded 观察者将在将子节点添加到该节点时自动向应用程序发送事件。我认为这段代码的方式是,你正在观察一个观察者。此外,您说 .onAppear 是罪魁祸首是正确的,因为每次视图出现时都会重新运行代码。我建议在第一次实例化视图时使用自定义初始化程序
init(_来设置 firebase 观察者。 -
这个自定义初始化会执行一次吗?还是每次我换出视图并返回视图时它会不断初始化?
-
它会在视图实例化时执行。
.onAppear在视图出现/消失/出现等时执行。 -
@Karim,你最终解决了这个问题吗?
-
嘿@Xeaza,是的,我做到了。我将在下面发布答案以查看过程。
标签: swift firebase firebase-realtime-database swiftui swiftui-list