swiftui @State 值取决于@ObservedObject ViewModel 初始化错误

swiftui @State value depends on @ObservedObject ViewModel init error

我有简单的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)
                  }
                }
            }
        }
 }
}

错误文本:

Cannot use instance member 'viewModel' within property initializer; property initializers run before 'self' is available

我尝试用 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' used before all stored properties are initialized

这引发了我在 init()

上调用 viewModel

如何解决? @State 我用于卡片视图。为了便于理解,我简化了视图。

这是可能的解决方案

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))
    }

首先将状态变量初始化为一个空数组

@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)
}