【发布时间】:2020-07-16 13:34:16
【问题描述】:
在下面的代码(项目中某些代码的精简版)中,我使用的是具有两个视图的 MVVM 模式:
- ViewA - 显示存储在 ObservableObject ViewModel 中的值;
- ViewB - 显示相同的值并具有一个更改该值的滑块,该滑块使用绑定传递给视图。
在 ViewModelA 内部,我有一个计算属性,它既可以避免视图直接访问模型,又可以在模型(正在显示的那个)内部的值发生更改时执行一些其他操作。
我还使用 Binding 将该计算值传递给 ViewModelB,它充当 ViewB 的 StateObject。但是,当拖动 Slider 以更改该值时,ViewA 上的值会更改,但 ViewB 上的值不会更改,并且滑块本身不会滑动。正如预期的那样,在调试时,Binding 中的 WrappedValue 没有改变。
但是变化是如何向上传播的(我想是通过绑定的设置器)而不是向下传播回 ViewB?
我想只有当变量在某处被复制并且仅在一个地方发生更改时才会发生这种情况,但我似乎无法理解在哪里或是否实际发生了这种情况。
提前致谢!
观看次数:
import SwiftUI
struct ContentView: View {
@StateObject var viewModelA = ViewModelA()
var body: some View {
VStack{
ViewA(value: viewModelA.value)
ViewB(value: $viewModelA.value)
}
}
}
struct ViewA: View {
let value: Double
var body: some View {
Text("\(value)").padding()
}
}
struct ViewB: View {
@StateObject var viewModelB: ViewModelB
init(value: Binding<Double>){
_viewModelB = StateObject(wrappedValue: ViewModelB(value: value))
}
var body: some View {
VStack{
Text("\(viewModelB.value)")
Slider(value: $viewModelB.value, in: 0...1)
}
}
}
视图模型:
class ViewModelA: ObservableObject {
@Published var model = Model()
var value: Double {
get {
model.value
}
set {
model.value = newValue
// perform other checks and operations
}
}
}
class ViewModelB: ObservableObject {
@Binding var value: Double
init(value: Binding<Double>){
self._value = value
}
}
型号:
struct Model {
var value: Double = 0
}
【问题讨论】:
-
您通常不会在视图模型中使用绑定。绑定用于视图的值类型属性。
-
是的,我从未见过有人在 ViewModels 中使用 Binding,但如果我坚持使用 mvvm,其中 View 和 Model 之间的连接应该通过 ViewModel 进行,所以如果我想更改一个值存储在模型中,其中包含在整个应用程序中使用的信息,例如滑块,我看到的唯一选项是每个模型仅使用一个 ViewModel,或者必须通过绑定在 ViewModel 之间传递模型(或其属性)(并且我不明白为什么不)。还是我错过了什么?
-
绑定是为了别的东西,所以你没有正确使用它。最佳实践是将视图的角色减少到单个作业。如果您需要在多个地方更改单个模型,可以使用
@EnvironmentObject将其“注入”,也可以使用其视图模型实例化视图。
标签: mvvm binding swiftui observableobject