提问人:user924223 提问时间:11/10/2023 最后编辑:user924223 更新时间:11/12/2023 访问量:49
如何在 Compose 上使用 android room (Kotlin) 返回新插入的项目(行)ID?
How to return newly inserted item(row) id using android room (Kotlin) on Compose?
问:
我需要获取添加到 ROOM 数据库表的记录的自动生成的 ID。
为了回答我的问题,我找到了以下答案:文本
但就我而言,这不是一个解决方案,因为在 Compose 中我不能使用代码:lifecycleScope.launch
//DAO
@Insert
suspend fun addwarrantyget(warrantyEntity: WarrantyEntity): Long
//Repository
suspend fun addwarrantyget(warrantyEntity: WarrantyEntity):Long {
return inventoryDB.warrantyDao().addwarrantyget(warrantyEntity)
}
//viewModel
fun addwarrantyget(warranty: WarrantyEntity) =
viewModelScope.launch {
repository.addwarrantyget(warranty)
}
//Inside Compose Fun
lifecycleScope.launch {
val id = viewModel.addwarrantyget(warranty)
Log.i("INSERT_ID", "Inserted ID is: $id")
}
根据建议和我的理解:
我补充道:
视图模型
private val _newItemId = MutableStateFlow(-1L)
val newItemId: StateFlow<Long> = _newItemId
fun addwarrantyget(warranty: WarrantyEntity) = viewModelScope.launch {
val newId = repository.addwarrantyget(warranty)
_newItemId.emit(newId!!)
}
Compose 函数提取
Button(
onClick = {
viewModel.addwarrantyget(
WarrantyEntity(
0,
null,
insn,
indescription,
null,
instartdateP.value,
inenddateP.value,
inprovider,
instartdateM.value,
inenddateM.value,
inmanufacturer
)
)
val newItemID by viewModel.newItemId.collectAsStateWithLifecycle()
LaunchedEffect(newItemID) {
if (newItemID == -1L) return@LaunchedEffect
// Do what you need with the new id here
warrantyId.value = viewModel.newItemId
mToast("Warranty Added", mContext)
}
mToast("Warranty Added", mContext)
},
colors = ButtonDefaults.buttonColors(Color.Blue)
) {
Text(text = "Add Warranty")
}
collectAsStateWithLifecycle:给出未定义的引用错误
warrantyId.value = viewModel.newItemId:出现“需要长时间查找 StateFlow”错误
LaunchedEffect:给出@Composable调用只能从上下文中发生......
答:
在 compose 中,你有 LaunchedEffect。您不会在调用的同一位置获取 id,但您可以从 as 状态中使用新的 id 值。viewModel.addwarrantyget(warranty)
viewModel
视图模型
private val _newItemId = MutableStateFlow(-1)
val newItemId: StateFlow<Int> = _newItemId
fun addwarrantyget(warranty: WarrantyEntity) = viewModelScope.launch {
val newId = repository.addwarrantyget(warranty)
_newItemId.emit(newId)
}
可组合
val newItemID by viewModel.newItemId.collectAsStateWithLifecycle()
LaunchedEffect(newItemID) {
if (newItemID == -1) return@LaunchedEffect
// Do what you need with the new id here
}
请注意,我设置了过滤掉默认值,当然还有其他方法可以做到这一点。newItemID
-1
编辑:
关于错误。已经包含新 id 的值,您无需再次读取它。Require Long Found StateFlow
newItemID
viewModel
mToast("New id: $newItemID", mContext)
请阅读有关国家的信息,以更好地了解这里正在发生的事情。
关于错误。正如错误所说,(作为可组合函数)不能从 lambda 调用,这不是可组合函数。请务必了解,使用状态和调用并不绑定在一起。您可以改为将 放入可组合屏幕级别。@Composable invocations can only happen from the context...
LaunchedEffect
onClick
newItemId
viewModel.addwarrantyget()
LaunchedEffect
@Composable
fun YourScreen(
viewModel: YourViewModel = viewModel()
) {
// other code
val newItemID by viewModel.newItemId.collectAsStateWithLifecycle()
LaunchedEffect(newItemID) {
if (newItemID == -1) return@LaunchedEffect
mToast("New id: $newItemID", mContext)
}
// other composables
}
评论