SwiftUI Можно ли поместить ObservableObject в другой ObservableObject? - PullRequest
0 голосов
/ 10 июля 2020

У меня есть представление под названием PurchaseView. В этом представлении отображаются сведения о покупке, о том, что было куплено и кто ее купил. Что я делаю, так это то, что в этом представлении я помещаю ItemView и ClientView внутрь PurchaseView. ItemView и ClientView являются общими и используются в других частях моего приложения. У них есть свои собственные ViewModels.

Я также пытался поставить ItemViewModel и ClientViewModel внутри PurchaseViewModel, но я не знаю, можно ли поместить ObservableObject внутрь другого ObservableObject. Это хороший подход или внутри ObservableObject не должно быть ObservableObject? Что из следующего лучше?

Это?

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

    //
}

Или это?

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

    var body: some View {
        //
    }
}

Модель для покупки:

class Purchase {
    let id: String
    let total: Double
    // ...
    var item: Item?
    var client: Client?
}

1 Ответ

0 голосов
/ 19 июля 2020

Ваше первое решение не будет работать, так как изменения вложенных ObservableObjects не распространяются вверх:

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

Здесь можно найти обходной путь: Как указать представления SwiftUI для привязки к вложенным ObservableObjects .

Ваш второй подход верен и будет работать в большинстве случаев:

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

Если вы используете ObservableObject для многих представлений, вы можете вместо этого внедрить его в среду и получить доступ как @EnvironmentObject.

В качестве альтернативы вы можете сделать свои вложенные объекты ObservableObject структурами :

class PurchaseViewModel: ObservableObject {
    @Published var clientViewModel: ClientViewModel // <- add `@Published`
    ...
}
struct ClientViewModel { // <- use `struct` instead of `class`
    ...
}

Обратите внимание, что ваш ClientViewModel будет становиться новой структурой каждый раз, когда она (или любая из его свойства) изменяется - этим решением не следует злоупотреблять (особенно для сложных ViewModels).

...