【问题标题】:swiftui @State value depends on @ObservedObject ViewModel init errorswiftui @State 值取决于 @ObservedObject ViewModel 初始化错误
【发布时间】:2020-10-29 15:26:07
【问题描述】:

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

这引发了我在init()上调用viewModel

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

【问题讨论】:

标签: swift swiftui combine


【解决方案1】:

这是可能的解决方案

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2019-11-03
      • 1970-01-01
      • 2022-11-10
      • 1970-01-01
      • 2021-12-20
      • 2023-01-21
      • 2021-10-28
      相关资源
      最近更新 更多