问题描述
我发现很难为SwiftUI应用程序确定最佳的架构模式,但是目前,我坚持使用MVVM,因为从概念上讲,这很合适。
我试图避免SwiftUI层对业务逻辑和导航结构有太多了解,但正在努力决定如何最好地实现这一目标。
这是原型视图模型(没有用于导航的实现):
@dynamicMemberLookup
final class PatientListViewModel: ViewModelType {
struct State {
var patients: [PatientSummaryViewModel]
}
@Published var state: State = State(patients: []) {
willSet { print("Received: \(newValue)") }
}
enum Input {
case onNewPatient
}
private let service: PatientServiceType
private var cancellables = Set<AnyCancellable>()
init(service: PatientServiceType) {
self.service = service
service.fetchAll()
.receive(on: DispatchQueue.main)
.map { patients in
patients.map {
PatientSummaryViewModel(patient: $0)
}
}
.sink { [weak self] patientViewModel in
self?.state.patients = patientViewModel
}
.store(in: &cancellables)
}
func action(_ input: Input) {
switch input {
case .onNewPatient:
print("Create new view and associated viewModel here but how does SwiftUI access it?")
}
}
subscript<Value>(dynamicMember keyPath: KeyPath<State,Value>) -> Value {
state[keyPath: keyPath]
}
}
关联的SwiftUI视图:
struct PatientListView: View {
@ObservedObject var viewModel: PatientListViewModel
var body: some View {
NavigationView {
List(viewModel.patients) { viewModel in
NavigationLink(
destination:
PatientSummaryView(viewModel: viewModel),label: {
PatientCell(patient: viewModel.patient)
})
}
.navigationBarItems(leading: EditButton(),trailing: Button(action: {
// call to viewmodel to get new view and correctly constructed viewModel
},label: { Image(systemName: "plus")
.font(.title2)
}))
.navigationBarTitle("Patients")
}
}
}
目前,有几种解决方案可供展示:
-
修改动作(_ input :)以原位创建View,然后将其返回给调用它的View。并非所有动作都需要进行导航,因此我需要添加@discardableresult,其中许多动作必须返回EmptyView(),然后我需要做一些与类型擦除视图有关的舞蹈
-
修改视图模型状态内部结构以包括“下一个视图”属性,该属性在需要新视图时由action(_ :)更新。尽管将状态保持在一个地方的想法很吸引人,但这还是有点笨拙
-
最后,我对传递给视图模型并用于构造所需视图的回调/关闭有一些模糊的想法,但由于我仍然发现关闭语法令人困惑,因此我很难将其可视化使用Views
欢迎想法,指点和批评! ;-)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)