8

我知道EnvironmentObject属性包装器可用于将对象传递给视图。我有一个会话对象,我将其传递给我的意见。现在我需要将它传递给我的模型类之一(即非视图)。理想情况下,这个模型(接收会话对象)被实例化为StateObject.

struct CreditDetailsView: View {
  @EnvironmentObject var session: Session
  @StateObject var transactionsModel = TransactionsModel(token: session.token)

上面的代码将不起作用(可以理解),因为:

cannot use instance member 'session' within property initializer; property initializers run before 'self' is available

关于如何在会话中传递的任何建议TransactionsModel

4

3 回答 3

3

尝试将道具中的 StateObject 初始化为.onAppear()子视图,如下所示:

struct CreditDetailsView: View {
  @EnvironmentObject var session: Session
  @StateObject var transactionsModel: TransactionModel?
  
  var body: some View {
    SomeChildView()
      .onAppear(perform: {
        transactionModel = TransactionModel(token: session.token)
      })
  }
}

这样,当视图呈现在屏幕上时,变量就会被初始化。将道具添加到哪个子视图并不重要onAppear,只要它在父视图中立即呈现即可。

于 2021-05-27T04:23:49.287 回答
1

这是一个不正确的答案。请查看上面选择的答案。

您可以session访问init. 在这种情况下,transactionsModel应该以任何方式进行已经初始化。

@EnvironmentObject var session: Session
@StateObject var transactionsModel = TransitionalModel(token: "")

init() {
    let token = self.session.token
    _transactionsModel = StateObject(wrappedValue: TransitionalModel(token: token))
}

虽然这是不可能的,但我不确定这是否是在他们之间传递一些东西的好方法,这些东西看起来像是在 View 的不同级别。

于 2021-05-27T04:32:08.337 回答
1

我发现这样做的最好方法(因为你不能有一个可选的 StateObject)是:

struct CreditDetailsView: View {
  @EnvironmentObject var session: Session
  @StateObject var localModel = LocalModel()
  
  var body: some View {
    SomeChildView()
      .onAppear {
        localModel.transactionModel = TransactionModel(token: session.token)
      }
  }

  class LocalModel: ObservableObject {
    @Published transactionModel: TransactionModel?
  }
}
于 2021-12-04T09:45:54.830 回答