Cách nói với các khung nhìn SwiftUI để liên kết với các ObservableObjects lồng nhau


18

Tôi có một chế độ xem SwiftUI có trong một môi trường được gọi là appModel. Sau đó nó đọc giá trị appModel.submodel.counttrong bodyphương thức của nó . Tôi hy vọng điều này sẽ ràng buộc quan điểm của tôi với tài sản counttrên submodelđể nó hiển thị lại khi tài sản cập nhật, nhưng điều này dường như không xảy ra.

Đây có phải là một lỗi? Và nếu không, cách thành ngữ để có các khung nhìn liên kết với các thuộc tính lồng nhau của các đối tượng môi trường trong SwiftUI là gì?

Cụ thể, mô hình của tôi trông như thế này ...

class Submodel: ObservableObject {
  @Published var count = 0
}

class AppModel: ObservableObject {
  @Published var submodel: Submodel = Submodel()
}

Và quan điểm của tôi trông như thế này ...

struct ContentView: View {
  @EnvironmentObject var appModel: AppModel

  var body: some View {
    Text("Count: \(appModel.submodel.count)")
      .onTapGesture {
        self.appModel.submodel.count += 1
      }
  }
}

Khi tôi chạy ứng dụng và nhấp vào nhãn, thuộc counttính sẽ tăng nhưng nhãn không cập nhật.

Tôi có thể khắc phục điều này bằng cách chuyển vào appModel.submodelnhư một tài sản ContentView, nhưng tôi muốn tránh làm như vậy nếu có thể.


Tôi cũng đang thiết kế ứng dụng của mình như thế này. Tôi thường có một đối tượng Ứng dụng toàn cầu trong phát triển ứng dụng trong quá khứ. Có ai khác nghĩ rằng thiết kế của một lớp "Ứng dụng" siêu hạng này là biến môi trường sẽ trở thành thông lệ tiêu chuẩn không? Tôi cũng đã xem xét sử dụng nhiều môi trường môi trường nhưng điều đó thật khó để duy trì.
Michael Ozeryansky

Câu trả lời:


22

Các mô hình lồng nhau chưa hoạt động trong SwiftUI, nhưng bạn có thể làm một cái gì đó như thế này

class Submodel: ObservableObject {
    @Published var count = 0
}

class AppModel: ObservableObject {
    @Published var submodel: Submodel = Submodel()

    var anyCancellable: AnyCancellable? = nil

    init() {
        anyCancellable = submodel.objectWillChange.sink { (_) in
            self.objectWillChange.send()
        }
    } 
}

Về cơ bản, bạn AppModelnắm bắt sự kiện từ đó Submodelvà gửi thêm cho Chế độ xem

Biên tập:

Nếu bạn không cần SubModelphải là lớp, thì bạn cũng có thể thử một cái gì đó như thế này:

struct Submodel{
    var count = 0
}

class AppModel: ObservableObject {
    @Published var submodel: Submodel = Submodel()
}

Cảm ơn, điều này rất hữu ích! Khi bạn nói "Các mô hình lồng nhau chưa hoạt động trong SwiftUI", bạn có biết chắc chắn rằng chúng được lên kế hoạch không?
rjkaplan

Tôi không chắc chắn, nhưng theo tôi nó nên hoạt động, tôi cũng sử dụng một cái gì đó tương tự trong proj của mình, vì vậy nếu tôi tìm thấy một cách tiếp cận tốt hơn tôi sẽ đi kèm với một chỉnh sửa
Sorin Lica

@SorinLica nên Submodelđược ObservableObject loại?
Farhan Amjad

Nó đang hoạt động! Giải pháp tuyệt vời!
Md Shahed Hossain

1

Tất cả ba ViewModels có thể giao tiếp và cập nhật

// First ViewModel
class FirstViewModel: ObservableObject {
var facadeViewModel: FacadeViewModels

facadeViewModel.firstViewModelUpdateSecondViewModel()
}

// Second ViewModel
class SecondViewModel: ObservableObject {

}

// FacadeViewModels Combine Both 

import Combine // so you can update thru nested Observable Objects

class FacadeViewModels: ObservableObject { 
lazy var firstViewModel: FirstViewModel = FirstViewModel(facadeViewModel: self)
  @Published var secondViewModel = secondViewModel()
}

var anyCancellable = Set<AnyCancellable>()

init() {
firstViewModel.objectWillChange.sink {
            self.objectWillChange.send()
        }.store(in: &anyCancellable)

secondViewModel.objectWillChange.sink {
            self.objectWillChange.send()
        }.store(in: &anyCancellable)
}

func firstViewModelUpdateSecondViewModel() {
     //Change something on secondViewModel
secondViewModel
}

Cảm ơn bạn Sorin cho giải pháp Kết hợp.


Bạn có thể cập nhật mã? nó có nhiều lỗi biên dịch
DevB2F

-2

Có vẻ như lỗi. Khi tôi cập nhật xcode lên phiên bản mới nhất, nó sẽ hoạt động chính xác khi liên kết với ObservableObjects lồng nhau


Bạn có thể làm rõ phiên bản xcode nào bạn đang sử dụng không? Tôi hiện đang có Xcode 11.0 và gặp vấn đề này. Tôi đã gặp sự cố khi nâng cấp lên 11.1, nó sẽ không vượt quá 80%.
Michael Ozeryansky
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.