在SwiftUI中非视图类之间传递环境对象

10

我了解到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
3个回答

4

尝试在 .onAppear() 属性中将 StateObject 初始化为子视图,例如:

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

这样,在视图渲染在屏幕上时,变量将被初始化。添加onAppear属性的子视图并不是很重要,只要它在父视图之后尽快呈现即可。


谢谢!在另一种情况下,我能够在按钮按下的onAction部分传递令牌。所以我猜你上面识别的方法和按钮按下是使这个工作的两个例子。 - Pradyot
没问题,希望能对你有所帮助 :) - Finley
你如何传递环境对象本身的引用,而不仅仅是其中一个属性(在这种情况下是token属性)的引用?我尝试过了,但是出现了大量错误。 - Soferio

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

-1

这是一个错误的答案。请查看上面选择的答案。

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

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

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

虽然这是不可能的,但我不确定在视图层面上看起来处于不同级别的它们之间传递某些东西是否是一个好方法。


我实际上没有看到任何在视图上提供init的代码。但是想想,没有什么可以阻止你这样做。感谢您指出这一点。我只需调用模型上的方法并通过init提供令牌即可。 - Pradyot
关于在 init 中提供某些内容,据我所知这是一种常见的模式。当您需要将某个值传递给视图并希望将其用作特定 @State/@StateObject 的初始值时,通常会使用它。但是,在这种情况下,通常会使用指定的 init 从外部接收该值。 - Kyokook Hwang
1
环境在Viewinit方法中不可用。这将导致致命错误,无法找到该类型的ObservableObject。 - Patrick Wynne
哦,我没有测试过。对于错误的答案感到抱歉。我会在答案顶部添加注释。 - Kyokook Hwang

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接