如何在Compose上使用android room(Kotlin)返回新插入的项目(行)id?

atmip9wb  于 2023-11-21  发布在  Kotlin
关注(0)|答案(1)|浏览(133)

我需要得到自动生成的ID的记录添加到一个房间数据库表。
为了回答我的问题,我找到了以下答案:text
但在我的情况下不是一个解决方案,因为在撰写我不能使用代码: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")
}

字符串
根据建议和我的理解:
我补充道:
//viewModel

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")
            }


collectAsStateWithError:给出未定义的引用错误
SystemId.value = viewModel.newItemId:给出Require Long Found StateFlow错误
LaunchedEffect:给出了@Composable调用只能从上下文中发生.

n6lpvg4x

n6lpvg4x1#

在compose中,你有LaunchedEffect。你不会在调用viewModel.addwarrantyget(warranty)的同一个地方获得id,但是你可以从viewModel中使用新的id值作为状态。
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,当然还有其他方法可以做到这一点。
编辑:
关于Require Long Found StateFlow错误。newItemID已经包含新id的值,您不需要再次从viewModel读取它。

mToast("New id: $newItemID", mContext)


请阅读States以更好地了解这里发生的事情。
关于@Composable invocations can only happen from the context...错误。正如错误所说,LaunchedEffect(作为一个可组合函数)不能从onClick lambda调用,这不是一个可组合函数。重要的是要理解,消费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
}

相关问题