问题描述
我有一个LoginView,如果用户未登录,则显示一个RegisterView;如果用户未登录,则显示一个ContentView:
I have a LoginView that shows a RegisterView if the user is not logged in, and a ContentView if he is logged in:
struct LoginView: View {
@EnvironmentObject var userManager: UserManager
var body: some View {
Group {
if userManager.isRegistered {
ContentView()
} else {
RegisterView()
}
}
}
}
ContentView
具有三个 ObservedObject
属性,这些属性用于结合使用以从具有其余api的服务器中获取内容.
ContentView
have three ObservedObject
properties, that uses combine to fetch content from a server with rest api's.
struct ContentView: View {
@EnvironmentObject var userManager: UserManager
@ObservedObject var usersStore = UsersStore()
@ObservedObject var rolesStore = RolesStore()
@ObservedObject var elementsStore = ElementsStore()
var body: some View {
NavigationView {
ZStack {
Image("stell")
.resizable()
.aspectRatio(contentMode: .fit)
.opacity(0.1)
VStack(alignment: .leading, spacing: 5) {
NavigationLink(destination: UsersView(usersStore: usersStore) ) {
Text("Users")
}
NavigationLink(destination: RolesView(rolesStore: rolesStore)) {
Text("Roles")
}
NavigationLink(destination: ElementsView(elements: $elementsStore.elements)) {
Text("Elements")
}
}.font(.title).padding(20)
}.navigationBarTitle(Text("STELL"))
}
}
}
我的问题是我想从任何observedObjects引用 userManager
,例如当会话令牌过期时,其余api返回 401 Unauthorized
.然后,我希望ObservedObject将 userManager
中的 isRegistered
标志设置为 false
,以便自动显示 RegisterView
.但是我该怎么办呢?我无法在任何ObservedObject属性初始化程序中设置对 userManager
的引用,因为编译器抱怨属性初始化程序在 self
可用之前就运行了.
The problem I have is that I want to reference userManager
from any of the observedObjects, e.g. when the rest api's returns 401 Unauthorized
when the session token has expired. Then I want the ObservedObject to set the isRegistered
flag in userManager
to false
so the RegisterView
is automatically shown. But how can I do that? I can't set a reference to userManager
in any of the ObservedObject property initializers, because the compiler complains about property initializers is run before self
is available.
推荐答案
在这种情况下,我将通过构造函数使用依赖项注入...下面显示了 UsersStore
示例的可能方法,对于其他示例会一样
I would use in this case dependency injection via constructor... below is show possible approach on example of UsersStore
, for others it would be the same
UsersStore
class UsersStore: ObservableObject {
var manager: UserManager
init(manager: UserManager) { // << inject UserManager via constructor
self.manager = manager
}
...
}
ContentView
struct ContentView: View {
@EnvironmentObject var userManager: UserManager
@ObservedObject var usersStore: UsersStore
init(usersStore: UsersStore) {
self.usersStore = usersStore // << inject UsersStore via contructor
}
用法更改
struct LoginView: View {
@EnvironmentObject var userManager: UserManager
var body: some View {
Group {
if userManager.isRegistered {
// userManager is valid here some UsersStore can be created
ContentView(usersStore: UsersStore(manager: self.userManager))
这篇关于在ObservableObject中引用EnvironmentObject的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!