【问题标题】:Is there a way decouple views from view models like the following?有没有办法将视图与视图模型分离,如下所示?
【发布时间】:2020-04-12 11:12:16
【问题描述】:

我的目标是两件事: 1.根据视图模型协议而不是具体类来制作视图。 2. 子视图从环境中获取视图模型,而不是通过视图层次结构传递它 我已经提到了我的目标,所以如果有完全不同的方式来实现它们,我愿意接受建议。 当然,这是尝试过但失败并引发奇怪错误的方法:

struct ContentView: View {
    var body: some View {
        NavigationView {
            MyView()
        }
    }
}

struct MyView: View {
    @EnvironmentObject var viewModel: some ViewModelProtocol

    var body: some View {
        HStack {
            TextField("Enter something...", text:$viewModel.text)
            Text(viewModel.greetings)
        }
    }
}

//MARK:- View Model
protocol ViewModelProtocol: ObservableObject {
    var greetings: String { get }
    var text: String { get set }
}

class ConcreteViewModel: ViewModelProtocol {
    var greetings: String { "Hello everyone..!" }
    @Published var text = ""
}

//MARK:- Usage
let parent = ContentView().environmentObject(ConcreteViewModel())

【问题讨论】:

    标签: swiftui combine


    【解决方案1】:

    有,但不是很漂亮。

    您遇到了问题,因为编译器无法理解它应该如何推断some protocol 应该是什么type

    some 在声明你的观点时起作用的原因是它是从你提供给它的任何东西的类型中推断出来的。

    如果您让视图结构采用通用视图模型类型,那么您可以启动并编译它。

    struct MyView<ViewModel: ViewModelProtocol>: View {
        @EnvironmentObject var viewModel: ViewModel
    
        var body: some View {
            Text(viewModel.greetings)
        }
    }
    

    这里的遗憾是,您现在必须在使用此视图时声明视图模型的 type,如下所示:

    let test: MyView<ConcreteViewModel> = MyView()
    

    【讨论】:

    • 没错。我不希望内容视图了解有关“MyView”视图模型具体类型的任何信息。实际上我试图逃避通用解决方案,找不到解决办法。所以我决定发布一个问题?。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-19
    • 1970-01-01
    • 2016-01-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多