【发布时间】:2020-03-23 07:01:22
【问题描述】:
我正在尝试弄清楚如何在父子关系中的两个 ViewModel 之间正确传递一个对象或一组值,以便在更新子 ViewModel 时,更改气泡会回到父级。
这在仅使用 SwiftUI 视图并直接绑定到商店时非常简单,但我希望将字段验证等业务逻辑与 SwiftUI 视图分开。
下面的代码显示了当父级更新时子级更新(如预期),但我需要以某种方式将子级中更改的值传递回父级。我对移动应用程序开发非常陌生,并且仍在学习,所以我确定我错过了一些非常简单的东西。
import SwiftUI
import Combine
struct Person: Hashable {
var givenName: String
var familyName: String
}
// my person store - in the real app it's backed by coredata
class PersonStore: ObservableObject {
@Published var people: [Person] = [
Person(
givenName: "Test",
familyName: "Person"
)
]
static let shared = PersonStore()
}
// app entrypoint
struct PersonView: View {
@ObservedObject var viewModel: PersonView_ViewModel = PersonView_ViewModel()
var body: some View {
NavigationView {
VStack {
List(viewModel.people.indices, id: \.self) { idx in
NavigationLink(destination: PersonDetailView(viewModel: PersonDetailView_ViewModel(personIndex: idx))) {
Text(self.viewModel.people[idx].givenName)
}
}
}
}
}
}
class PersonView_ViewModel: ObservableObject {
@Published var people: [Person] = PersonStore.shared.people
}
// this is the detail view
struct PersonDetailView: View {
@ObservedObject var viewModel: PersonDetailView_ViewModel
var body: some View {
Form {
Section(header: Text("Parent View")) {
VStack {
TextField("Given Name", text: self.$viewModel.person.givenName)
Divider()
TextField("Family Name", text: self.$viewModel.person.familyName)
}
}
PersonBasicDetails(viewModel: PersonBasicDetails_ViewModel(person: viewModel.person))
}
}
}
// viewmodel associated with detail view
class PersonDetailView_ViewModel: ObservableObject {
@Published var person: Person
init(personIndex: Int) {
self.person = PersonStore.shared.people[personIndex]
}
}
// this is the child view - in the real app there are multiple sections which are conditionally rendered
struct PersonBasicDetails: View {
@ObservedObject var viewModel: PersonBasicDetails_ViewModel
var body: some View {
Section(header: Text("Child View")) {
VStack {
TextField("Given Name", text: self.$viewModel.person.givenName)
Divider()
TextField("Family Name", text: self.$viewModel.person.familyName)
}
}
}
}
class PersonBasicDetails_ViewModel: ObservableObject {
@Published var person: Person
init(person: Person) {
self.person = person
}
}
struct PersonView_Previews: PreviewProvider {
static var previews: some View {
PersonView()
}
}
【问题讨论】: