swift - 如何在 Swift 中连接模型和视图模型的已发布属性?
问题描述
让我们假设一个模型,它实现了协议ObservableObject
并且有一个@Published
属性name
。
// MARK: Model
class ContentSinglePropertyModel: ObservableObject {
@Published public var name: String
}
现在,我想在视图中显示该名称并name
在模型发生更改时更新视图。此外,我想使用 Model-View-ViewModel (MVVM) 模式来实现这一目标。
// MARK: ViewModel
final class ContentSinglePropertyViewModel: ObservableObject {
private let model: ContentSinglePropertyModel
@Published var name: String = ""
init() {
self.model = ContentSinglePropertyModel()
}
}
// MARK: View
struct ContentSinglePropertyView: View {
@ObservedObject var viewModel: ContentSinglePropertyViewModel
var body: some View {
Text(self.viewModel.name)
}
}
由于我不喜欢在视图模型中公开模型或其属性的想法,因此一种选择是将模型的属性包装name
在视图模型中。我的问题是:如何以name
最惯用的方式连接模型和视图模型?
我想出了通过使用 Combine 的assign方法来更新 viewmodel 属性的解决方案:
self.model.$name.assign(to: \.name, on: self).store(in: &self.cancellables)
有更好的解决方案吗?
我的工作示例:
import SwiftUI
import Combine
// MARK: Model
class ContentSinglePropertyModel: ObservableObject {
@Published public var name: String
init() {
self.name = "Initial value"
}
func doSomething() {
self.name = "Changed value"
}
}
// MARK: ViewModel
final class ContentSinglePropertyViewModel: ObservableObject {
private let model: ContentSinglePropertyModel
private var cancellables: Set<AnyCancellable> = []
@Published var name: String = ""
init() {
self.model = ContentSinglePropertyModel()
// glue Model and ViewModel
self.model.$name.assign(to: \.name, on: self).store(in: &self.cancellables)
}
func doSomething() {
self.model.doSomething()
}
}
// MARK: View
struct ContentSinglePropertyView: View {
@ObservedObject var viewModel: ContentSinglePropertyViewModel
var body: some View {
VStack {
Text(self.viewModel.name)
Button("Do something!", action: {
self.viewModel.doSomething()
})
}
}
}
struct ContentSinglePropertyView_Previews: PreviewProvider {
static var previews: some View {
ContentSinglePropertyView(viewModel: .init())
}
}
解决方案
推荐阅读
- python - 将原始 CFA 缓冲区保存到原始图像
- javascript - 阿波罗客户端在反应原生的初始重新加载中返回未定义
- javascript - 如何使用私有方法正确配置 ES6 类的 eslint?
- c# - 在页面级别实现 Asp.NET core 2.2 Sessionstate 或 tempdata 等效项
- javascript - Ajax errorThrown:内部服务器错误,但状态为 4
- android - 在 kotlin 中旋转 R.drawable
- asp.net-mvc - VS2019中如何自定义docker镜像名称
- eclipse-plugin - 如何用最新版本替换 RCP 项目中插件依赖项中存在的插件?
- google-apps-script - 仅在特定子文件夹中创建具有值和格式的电子表格备份
- c# - 由于 InitializedDatabases 列表,EntityFramework6 内存使用量很大