在协程内触发时双向数据绑定不起作用

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 字段必须是可观察的。

现在,没有任何东西告诉 Edi​​tText 该字段已更新并且需要重新绑定。您可能会从最初在绑定上设置 viewModel 看到“第一”。

查看the documentation 的可观察性。

My answer to another similar question 也可能有帮助。

【讨论】:

以上是关于在协程内触发时双向数据绑定不起作用的主要内容,如果未能解决你的问题,请参考以下文章

vue双向绑定时添加.sync不起作用的原因

Angular - 来自@Input的双向数据绑定不起作用

使用 ngModel 的 Angular 2 双向绑定不起作用

使用 ngModel 的 Angular 2 双向绑定不起作用

使用 ngModel 的 Angular 2 双向绑定不起作用

使用 ngModel 的 Angular 2 双向绑定不起作用