我正在与一个LiveData观察器挣扎,后者会触发两次。在我的片段中,我观察到一个LiveData
,如下所示,将viewLifeCycleOwner
用作LifeCycleOwner
private lateinit var retailViewModel: RetailsViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
retailViewModel = ViewModelProviders.of(this).get(RetailsViewModel::class.java)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
retailViewModel.retailLiveData.observe(viewLifecycleOwner, Observer {
// updating UI here, but firing twice!
}
retailViewModel.getRetailById(retail.id)
}
这是我的视图模型:
class RetailsViewModel(override val service: MyFoodyApiService = MyFoodyApiService.service) :
BaseViewModel(service) {
var retailLiveData: MutableLiveData<Retail> = MutableLiveData()
fun getRetailById(id: Int) {
scope.launch {
try {
val response =
service.getRetailById(authString, id).await()
when (response.isSuccessful) {
true -> {
response.body()?.let { payload ->
retailLiveData.postValue(payload.data)
} ?: run {
errorLiveData.postValue("An error occurred: ${response.message()}")
}
}
false -> errorLiveData.postValue("An error occurred: ${response.message()}")
}
} catch (e: Exception) {
noConnectionLiveData.postValue(true)
}
}
}
}
当我第一次运行该片段时,一切正常,但是当我转到其DetailFragment并返回时,retailLiveData
观察者回调被触发两次。根据{{3}}的介绍,这是一个已知问题,通过引入viewLifeCycleOwner
解决了这一问题,一旦片段的视图被破坏,它应该有助于删除活动的观察者,但是对于我来说似乎没有帮助。
答案 0 :(得分:2)
之所以发生这种情况,是因为当您打开另一个片段时,视图模型会保留值,但是该片段的视图被破坏了。当您回到片段时,将重新创建视图,并订阅 testPost(req: any, res: any) {
let { name, first_last_name, second_last_name, username, password, mail, phone, cellphone, history } = req.body;
let newClient = new Client({
name,
first_last_name,
second_last_name,
username,
password,
mail,
phone,
cellphone,
history:[]
});
newClient.save((error, client) => {
if (error) return res.status(500).send({ message: `Error: ${error}` });
res.status(200).send({ message: `Client ${client.name} saved` });
});
,该变量仍保留先前的值,并在片段移至开始状态时立即通知您的观察者。但是您正在retailLiveData
中调用retailViewModel.getRetailById(retail.id)
,因此一段时间后,值将更新,并再次通知观察者。
一种可能的解决方案是从视图模型的onViewCreated
方法调用getRetailById()
,然后将结果缓存到视图模型的生存期中。