SwiftUI 可以将 ObservableObject 放入另一个 ObservableObject 中吗?

Rex*_*xha 5 ios swift swiftui

我有一个名为PurchaseView. 此视图显示有关购买、购买的内容和购买者的详细信息。我正在做的是,在这个视图IM把两个ItemViewClientViewPurchaseViewItemView并且ClientView被共享并且在我的应用程序的其他部分使用。他们有自己的 ViewModel。

我也试过把ItemViewModelClientViewModel放在里面,PurchaseViewModel但我不知道把一个ObservableObject放在另一个里面是否可以ObservableObject。这是一个好方法还是不应该有任何ObservableObject内部ObservableObject?以下哪一项更好?

这个?

class PurchaseViewModel: ObservableObject {
    let clientViewModel: ClientViewModel
    let itemsViewModel: ItemViewModel

    //
}
Run Code Online (Sandbox Code Playgroud)

或这个?

struct PurchaseView: View {
    @ObservedObject var purchaseViewModel: PurchaseViewModel
    @ObservedObject var itemViewModel: ItemViewModel
    @ObservedObject var clientViewModel: ClientViewModel

    var body: some View {
        //
    }
}
Run Code Online (Sandbox Code Playgroud)

购买型号:

class Purchase {
    let id: String
    let total: Double
    // ...
    var item: Item?
    var client: Client?
}
Run Code Online (Sandbox Code Playgroud)

paw*_*222 4

您的第一个解决方案将不起作用,因为对嵌套 ObservableObjects 的更改不会向上传播:

class PurchaseViewModel: ObservableObject {
    let clientViewModel: ClientViewModel
    let itemsViewModel: ItemViewModel
    ...
}
Run Code Online (Sandbox Code Playgroud)

可以在这里找到解决方法:如何告诉 SwiftUI 视图绑定到嵌套的 ObservableObjects


您的第二种方法是正确的,并且适用于大多数情况:

struct PurchaseView: View {
    @ObservedObject var purchaseViewModel: PurchaseViewModel
    @ObservedObject var itemViewModel: ItemViewModel
    @ObservedObject var clientViewModel: ClientViewModel
    ...
}
Run Code Online (Sandbox Code Playgroud)

如果您共享ObservableObject多个视图,则可以将其注入到环境中并作为@EnvironmentObject.


或者,您可以将嵌套的 ObservableObjects 设为结构

class PurchaseViewModel: ObservableObject {
    @Published var clientViewModel: ClientViewModel // <- add `@Published`
    ...
}
Run Code Online (Sandbox Code Playgroud)
struct ClientViewModel { // <- use `struct` instead of `class`
    ...
}
Run Code Online (Sandbox Code Playgroud)

请注意,ClientViewModel每次它(或其任何属性)发生变化时,您都会成为一个新的结构 - 该解决方案不应该被过度使用(特别是对于复杂的 ViewModel)。