- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
有没有办法让 @Published
变量只在新值与旧值不同时才发布其值?
现在如果我们有
@Published var test: Bool = false
我们做到了
test = false
test = false
test = false
发布者被调用了 3 次。这很烦人,因为它有时会导致我的 SwiftUI View 被重新创建,因为在层次结构中较高的某个位置,发布者被设置为之前设置的值,通过另一个被触发的发布者(并且这会破坏文本字段输入,因为 View 模型通过发生这种情况时会重新创建层次结构)。
有没有办法只在从 false
变为 true
或反之亦然时发布?
一个示例场景:
我们在我们的应用程序中创建了一个用户对象,并且我们想向用户添加一辆车。如果没有找到汽车,应用程序应立即显示“添加汽车” View ,否则显示主应用程序 View 。为此,我们在某个地方有一个听众。在我们的顶层 View 中,我们有:
@ObservedObject var viewModel = UserViewModel()
var body: some View {
if !viewModel.hasVehicles {
return AnyView(AddVehicleView(viewModel:AddVehicleViewModel())
} else {
return AnyView(UserMainView(user: user))
}
}
}
在我们的 UserViewModel
我们有
class UserViewModel: ObservableObject {
@Published var hasVehicles: Bool = false
在 AddVehicleView
中,我们有一个表单,允许用户填写一些文本字段并保存车辆。
现在想象一下,由于某种原因,更新 hasVehicles
属性的代码被触发,但仍然没有车辆。会发生什么:
hasVehicles = false
并且顶层 View 被重新评估,导致 return AnyView(AddVehicleView(viewModel:AddVehicleViewModel())
被执行,并且我的带有文本字段的表单被清空。
我想在这种情况下,我可以通过将 AddVehicleViewModel()
作为属性放在 View
结构中来解决它,但是在这种情况下不会解决它我们希望它被执行多次,因为这意味着下次构建 View 时,它将显示我们上次创建该 View 时的数据,因为我们重用了 View 模型。
最佳答案
在更新属性的代码中使用 Combine 的 removeDuplicates()
运算符。例如, View 模型可以创建一个发布者,该发布者根据其他两个 bool 属性的值更新一个 bool 属性:
@Published var hasTrucks: Bool
@Published var hasCars: Bool
@Published var hasVehicles: Bool
func createVehiclePublisher() {
Publishers.CombineLatest($hasTrucks, $hasCars)
.map { $0 || $1 }
.removeDuplicates()
.assign(to: &$hasVehicles)
}
使用 removeDuplicates()
会导致 hasVehicles
仅在其值发生变化时更新。
关于swiftui - Combine 是否有仅在值实际更改时才发布的发布者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65905731/
我是一名优秀的程序员,十分优秀!