在协程内触发时双向数据绑定不起作用
Posted
技术标签:
【中文标题】在协程内触发时双向数据绑定不起作用【英文标题】:Two-way databinding not working when triggered inside coroutine 【发布时间】:2021-10-07 18:18:48 【问题描述】:在从 BE API 调用中获取一些数据后,我正在尝试通过 data-binding
更新 TextInputEditText
文本。如果代码不在协程内执行,我的解决方案将完美运行。如果在协程内设置变量 EditText
不会更新。
我的 XML 代码:
<com.google.android.material.textfield.TextInputEditText
android:layout_
android:layout_
android:text="@= viewModel.name " />
我的 viewModel 代码:
var name: String = ""
get() = field.trim()
set(value)
field = value
//some other unrelated code
...
fun getName()
name = "first"
viewModelScope.launch(Dispatchers.Main)
name = "second"
TextInputEditText
将更新为“第一”,但不会更新为“第二”。我已经尝试过与其他调度程序。我还通过调试器验证了两次都触发了“名称”变量设置器。它只是不更新EditText
。关于可能导致这种情况的任何想法?
【问题讨论】:
您正在更新协程内的firstName
变量而不是 name
变量。
@Amirhosein 这是我写问题时的错字(我编辑了问题以修复它)。我的代码中的变量名是正确的。
【参考方案1】:
在我的例子中,通过在以下代码中设置生命周期所有者属性的值来解决问题。数据绑定现在按预期完成。
override fun onViewCreated(view: View, savedInstanceState: Bundle?)
super.onViewCreated(view, savedInstanceState)
postDetailViewModel = ViewModelProvider(this)[PostDetailViewModel::class.java]
binding.varPostDetailViewModel = postDetailViewModel
binding.lifecycleOwner = this // Add this line
coroutineScope.launch
arguments?.let
val args = PostDetailFragmentArgs.fromBundle(it)
postDetailViewModel.getPostDetail(args.postID)
【讨论】:
【参考方案2】:您的name
字段必须是可观察的。
现在,没有任何东西告诉 EditText 该字段已更新并且需要重新绑定。您可能会从最初在绑定上设置 viewModel 看到“第一”。
查看the documentation 的可观察性。
My answer to another similar question 也可能有帮助。
【讨论】:
以上是关于在协程内触发时双向数据绑定不起作用的主要内容,如果未能解决你的问题,请参考以下文章
使用 ngModel 的 Angular 2 双向绑定不起作用
使用 ngModel 的 Angular 2 双向绑定不起作用