在ObservableObject中引用EnvironmentObject [英] Reference EnvironmentObject in ObservableObject

查看:57
本文介绍了在ObservableObject中引用EnvironmentObject的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆