英文:
Can val uiStateA be changed outside ViewModel in Code A?
问题
I know that asStateFlow()
将可将可变状态流表示为只读状态流,所以我认为val uiStateB
不能在 Code B 中的 InterestsViewModel
外部更改,这是一个不错的方式。
val uiStateA
是由 combine
生成的,可以在 Code A 中的 TaskDetailViewModel
外部更改吗?如果可以,Code A 是否是一个好的方式?
Code A
class TaskDetailViewModel @Inject constructor(
...
) : ViewModel() {
private val _userMessage: MutableStateFlow<Int?> = MutableStateFlow(null)
private val _isLoading = MutableStateFlow(false)
private val _isTaskDeleted = MutableStateFlow(false)
private val _taskAsync = taskRepository.getTaskStream(taskId)
val uiStateA: StateFlow<TaskDetailUiState> = combine(
_userMessage, _isLoading, _isTaskDeleted, _taskAsync
) { userMessage, isLoading, isTaskDeleted, taskAsync ->
when (taskAsync) {
...
}
} .stateIn(
scope = viewModelScope,
started = WhileUiSubscribed,
initialValue = TaskDetailUiState(isLoading = true)
)
}
Code B
class InterestsViewModel(
private val interestsRepository: InterestsRepository
) : ViewModel() {
private val _uiState = MutableStateFlow(InterestsUiState(loading = true))
val uiStateB: StateFlow<InterestsUiState> = _uiState.asStateFlow()
...
}
英文:
I know that asStateFlow()
will represent a mutable state flow as a read-only state flow, so I think the val uiStateB
can't be changed outside InterestsViewModel
in Code B, it's a good way.
val uiStateA
is generated by combine
, can val uiStateA
be changed outside TaskDetailViewModel
in Code A ? If so, is the Code A good way?
Code A
class TaskDetailViewModel @Inject constructor(
...
) : ViewModel() {
private val _userMessage: MutableStateFlow<Int?> = MutableStateFlow(null)
private val _isLoading = MutableStateFlow(false)
private val _isTaskDeleted = MutableStateFlow(false)
private val _taskAsync = taskRepository.getTaskStream(taskId)
val uiStateA: StateFlow<TaskDetailUiState> = combine(
_userMessage, _isLoading, _isTaskDeleted, _taskAsync
) { userMessage, isLoading, isTaskDeleted, taskAsync ->
when (taskAsync) {
...
}
} .stateIn(
scope = viewModelScope,
started = WhileUiSubscribed,
initialValue = TaskDetailUiState(isLoading = true)
)
}
Code B
class InterestsViewModel(
private val interestsRepository: InterestsRepository
) : ViewModel() {
private val _uiState = MutableStateFlow(InterestsUiState(loading = true))
val uiStateB: StateFlow<InterestsUiState> = _uiState.asStateFlow()
...
}
答案1
得分: 1
No. Vals 只能在初始化时设置一次。之后尝试更改它们将导致编译错误。如果您想要更改它(我不建议这样做,这将是一种尴尬的架构并可能引发错误),您可以使用 var。
但是值仍然可以发送到 StateFlow。因此,如果代码使用 uiStateA.value,它们将获得不同的值,因为它组合的流发生变化。
英文:
No. Vals can only be set once, at initialization. After that, attempting to change them will cause a compile error. If you want to change it (which I would not recommend, it would be an awkward architecture and open up bugs) you'd use a var instead.
However values can still be emitted to the stateflow. So if code did uiStateA.value they would get different values as the flows it combines change.
答案2
得分: 1
stateIn
创建了一个无法转换为MutableStateFlow的StateFlow,就像asStateFlow()
一样。因此,您不能通过uiStateA
引用更改value
或正在发射的内容。(除非通过可以实现几乎任何操作的反射。)
英文:
stateIn
creates a StateFlow that cannot be cast to MutableStateFlow, just like asStateFlow()
does. Therefore you cannot change the value
or what’s being emitted using the uiStateA
reference. (Except through reflection which can achieve pretty much anything.)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论