Mvvm 将@Binding/@状态绑定到@Publisher以解耦VM和视图层
我想解耦ViewModel和视图层,以提高视图的可测试性。 因此,我希望在视图中保留我的属性状态,并且只在需要时初始化它们。 但是我不能用@Published属性初始化@Binding或@States。有没有办法在init函数中耦合它们 我只是将下面的示例代码添加到 而不是Mvvm 将@Binding/@状态绑定到@Publisher以解耦VM和视图层,mvvm,swiftui,observableobject,Mvvm,Swiftui,Observableobject,我想解耦ViewModel和视图层,以提高视图的可测试性。 因此,我希望在视图中保留我的属性状态,并且只在需要时初始化它们。 但是我不能用@Published属性初始化@Binding或@States。有没有办法在init函数中耦合它们 我只是将下面的示例代码添加到 而不是 import SwiftUI class ViewModel: ObservableObject { @Published var str: String = "a" @Publishe
import SwiftUI
class ViewModel: ObservableObject {
@Published var str: String = "a"
@Published var int: Int = 1 { didSet { print("ViewModel int = \(int)")} }
init() {
print("ViewModel initialized")
}
}
struct ContentView: View {
@ObservedObject vM = ViewModel()
var body: some View {
Button(action: { vM.int += 1; print(int) }, label: {
Text("Button")
})
}
}
我希望在视图中不使用@ObservedObject来实现这一点
import SwiftUI
class ViewModel: ObservableObject {
@Published var str: String = "a"
@Published var int: Int = 1 { didSet { print("ViewModel int = \(int)")} }
init() {
print("ViewModel initialized")
}
}
struct ContentView: View {
@Binding var str: String
@Binding var int: Int
var body: some View {
Button(action: { int += 1; print(int) }, label: {
Text("Button")
})
}
}
extension ContentView {
init(viewModel:ObservedObject<ViewModel> = ObservedObject(wrappedValue: ViewModel())) {
// str: Binding<String> and viewModel.str: Published<String>.publisher
// type so that I cannot bind my bindings to viewModel. I must accomplish
// this by using @ObservedObject but this time my view couples with ViewModel
_str = viewModel.wrappedValue.$str
_int = viewModel.wrappedValue.$int
print("ViewCreated")
}
}
// Testing Init
ContentView(str: Binding<String>, int: Binding<Int>)
// ViewModel Init
ContentView(viewModel: ViewModel)
导入快捷界面
类ViewModel:ObservableObject{
@已发布的var str:String=“a”
@已发布的变量int:int=1{didSet{print(“ViewModel int=\(int)”)}
init(){
打印(“ViewModel已初始化”)
}
}
结构ContentView:View{
@绑定变量str:String
@绑定变量int:int
var body:一些观点{
按钮(操作:{int+=1;打印(int)},标签:{
文本(“按钮”)
})
}
}
扩展内容视图{
init(viewModel:ObservedObject=ObservedObject(wrappedValue:viewModel()){
//str:Binding和viewModel.str:Published.publisher
//键入,这样我就无法将绑定绑定到viewModel。我必须完成
//这是通过使用@ObservedObject实现的,但这次我的视图与ViewModel耦合
_str=viewModel.wrappedValue.$str
_int=viewModel.wrappedValue.$int
打印(“创建视图”)
}
}
//测试初始化
ContentView(str:Binding,int:Binding)
//视图模型初始化
ContentView(视图模型:视图模型)
这样我就无法将它们彼此绑定,我只想将我的绑定或状态属性绑定到已发布的属性。我意识到通过绑定(get:{},set{}),我可以实现这一点。如果任何人想要分离他们的ViewModel和View图层,他们可以使用以下方法:
import SwiftUI
class ViewModel: ObservableObject {
@Published var str: String = "a"
@Published var int: Int = 1 { didSet { print("ViewModel int = \(int)")} }
init() {
print("ViewModel initialized")
}
}
struct ContentView: View {
@Binding var str: String
@Binding var int: Int
var body: some View {
Button(action: { int += 1; print(int) }, label: {
Text("Button")
})
}
}
extension ContentView {
init(viewModel:ViewModel = ViewModel()) {
_str = Binding ( get: { viewModel.str }, set: { viewModel.str = $0 } )
_int = Binding ( get: { viewModel.int }, set: { viewModel.int = $0 } )
print("ViewCreated")
}
}
你是什么意思
@Binding
是指绑定到源自其他SwiftUI视图的值,而不是引用types@SergioBost我编辑我的问题,我想完全分离我的视图和ViewModel,这样我想在视图中设计我的视图状态,而不是使用观察对象,但同时我想有机会使用ViewModel初始化我的视图。