微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将@Binding / @State 绑定到@Publisher 以解耦VM 和View 层

如何解决将@Binding / @State 绑定到@Publisher 以解耦VM 和View 层

我想分离我的 viewmodel 和 View 层以提高我的视图的可测试性。 因此,我想将我的属性状态保留在视图中,并且仅在需要时初始化它们。 但是我无法使用 @Published 属性初始化我的 @Binding 或 @States。有没有办法将它们耦合到 init 函数中?

我只是在下面添加示例代码

代替

    stmt = (select(User)
                .where(id.in_(user_ids)))

我想在不使用 @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 {
    
    @Observedobject vM = viewmodel()
    
    var body: some View {
        Button(action: { vM.int += 1; print(int) },label: {
        Text("Button")
        })
    }
}

这样我就无法将它们相互绑定,我只想将我的绑定或状态属性绑定到已发布的属性

解决方法

我意识到通过 Binding(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")
    }

}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。