swiftui Значение @State зависит от ошибки инициализации @ObservedObject ViewModel - PullRequest
1 голос
/ 09 июля 2020

У меня простой viewModel:

final class EmployeeListViewModel: ObservableObject {
 @Published var list = [Employee]()
 init() {
  // some request
  self.list = [Employee, Employee]
 }
}

И есть view:

struct EmployeeView: View {
 @ObservedObject var viewModel = EmployeeListViewModel()
 @State private var showContents: [Bool] = Array(repeating: false, count: viewModel.list.count)// <- error throws here
 var body: some View {
        GeometryReader { fullView in
            ScrollView {
                VStack(spacing: 40) {
                  ForEach(self.viewModel.list) { employee in
                     Text(employee.firstName).foregroundColor(.black)
                  }
                }
            }
        }
 }
}

Текст ошибки:

Невозможно использовать экземпляр элемент viewModel в инициализаторе свойства; инициализаторы свойств запускаются до того, как 'self' станет доступным

Я попытался изменить его с помощью init:

struct EmployeeView: View {
 @ObservedObject var viewModel = EmployeeListViewModel()
 @State private var showContents: [Bool]

 init() {
        _showContents = State(initialValue: Array(repeating: false, count: viewModel.list.count)) // <- error
    }

 var body: some View {
        GeometryReader { fullView in
            ScrollView {
                VStack(spacing: 40) {
                  ForEach(self.viewModel.list) { employee in
                     Text(employee.firstName).foregroundColor(.black)
                  }
                }
            }
        }
 }
}

Но это также вызывает ошибку:

'self' используется перед инициализацией всех сохраненных свойств

это бросает на Я вызываю viewModel на init()

Как решить эту проблему? @ Состояние, которое я использую для просмотра карточек. Там я упростил представления для облегчения понимания.

Ответы [ 2 ]

1 голос
/ 09 июля 2020

Сначала инициализируйте переменную состояния в пустой массив

@State private var showContents: [Bool] = []

, затем установите его в init

init() {
    showContents = Array(repeating: false, count: viewModel.list.count)
 }

Вы не должны инициализировать свойство модели представления в представлении а лучше использовать инъекцию зависимостей

init(viewModel: EmployeeListViewModel) {
    self.viewModel = viewModel
    showContents = Array(repeating: false, count: viewModel.list.count)
}
0 голосов
/ 09 июля 2020

Вот возможное решение

struct EmployeeView: View {
 @ObservedObject var viewModel: EmployeeListViewModel     // << declare
 @State private var showContents: [Bool]                  // << declare

 init() {
       let vm = EmployeeListViewModel()   // create here !!

       // initialize both below
       self.viewModel = vm                     
       self._showContents = State(initialValue: Array(repeating: false, 
              count: vm.list.count))
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...