如何监听Kotlin数据类对象的本地变更以自动更新远端Firebase文档
问题根因
你当前的Delegates.observable是作用在data这个引用变量上,仅当你给data变量重新赋值一个全新的Data对象时才会触发回调。修改data指向的对象内部的字段时,data变量本身的引用没有变化,自然不会触发监听。
解决方案
方案1:将可观测逻辑下沉到数据类内部字段
给Data类的每个字段都加上Delegates.observable,同时在类内部定义字段变更的统一回调:
data class Data( description: String? = null, user_created_id: String? = null, user_responded_id: String? = null, status: Long? = null, ) { // 定义字段变更回调,可根据需求传入变更的字段名、新旧值 var onFieldChanged: ((fieldName: String, oldVal: Any?, newVal: Any?) -> Unit)? = null var description: String? by Delegates.observable(description) { prop, old, new -> onFieldChanged?.invoke(prop.name, old, new) } var user_created_id: String? by Delegates.observable(user_created_id) { prop, old, new -> onFieldChanged?.invoke(prop.name, old, new) } var user_responded_id: String? by Delegates.observable(user_responded_id) { prop, old, new -> onFieldChanged?.invoke(prop.name, old, new) } var status: Long? by Delegates.observable(status) { prop, old, new -> onFieldChanged?.invoke(prop.name, old, new) } }
使用时直接给Data实例绑定回调即可:
val localData = Data() localData.onFieldChanged = { fieldName, oldVal, newVal -> // 此处执行Firestore更新逻辑,可按需只上传变更的字段 log("$fieldName 从 $oldVal 变更为 $newVal") firebaseDocRef.update(fieldName, newVal) } // 后续修改任意字段都会自动触发回调 localData.description = "新描述"
注意:如果需要用该类做Firestore的序列化/反序列化,需要给无参构造留好默认值,上述写法已经满足要求。
方案2:修改数据后主动重新赋值给observable变量
如果不想改动原有数据类定义,也可以遵循数据类不可变修改的惯例,用copy方法生成新对象后赋值给data变量:
// 修改字段时用copy生成新实例重新赋值 data = data?.copy(description = "新描述")
这种写法会触发你原本写在data变量上的observable回调,直接在回调里把整个新对象写入Firestore即可:
override var data : Data? by Delegates.observable(Data()) { property, oldValue, newValue -> newValue?.let { log("对象发生变更,同步到Firebase") firebaseDocRef.set(it) } }
内容的提问来源于stack exchange,提问作者Liker
相关产品推荐
相关产品推荐

