繁体   English   中英

SwiftUI:在 ViewModel 之间传递数据

[英]SwiftUI: Passing Data between ViewModels

让我用简单的例子解释我的问题/问题。

我有第一个视图: UserView和 realted UserViewModel
我有第二种观点: UserDetailsView和相关的UserDetailsViewModel

UserViewModel ,我正在加载User object。
然后,我想将User object 传递给UserDetailsViewModel
这样UserDetailsViewModel就可以使用用户 object 进行操作。

需要明确的是,从简洁代码的角度来看,我不想在我的视图中保留User object。
View 应该只适用于ViewModel

这是一个代码:

struct UserView: View {
    @ObservedObject var viewModel = UserViewModel()

    var body: some View {
        VStack {
            Text(viewModel.user?.name ?? "")
            
            if let userDetailsViewModel = viewModel.userDetailsViewModel {
                NavigationLink {
                    UserDetailsView(viewModel: userDetailsViewModel)
                } label: {
                    Text("See user Details")
                }
            }
        }
    }
}

class UserViewModel: ObservableObject {
    @Published var user: User?
    @Published var userDetailsViewModel: UserDetailsViewModel?

    func fetchUser() {
        APIClient.shared.loadUser { user in
            self.user = user
            self.userDetailsViewModel = = .init(user:
                Binding(
                    get: {
                        self.user
                    },
                    set: {
                        self.user = $0
                    }
                )
            )
        }
    }
}


struct UserDetailsView: View {
    @ObservedObject var viewModel: UserDetailsViewModel

    var body: some View {
        VStack { 
            Text(viewModel.user.name)
            Text(viewModel.user.details)
        }
    }
}

class UserDetailsViewModel: ObservableObject {
    @Binding var user: User

    init(user: Binding<User>) {
        _user = user
    }

    func updateUserName(_ name: String) {
        APIClient.shared.updateUserName(name) { user in
            self.user = user
        }
    }
}

我将User作为@Binding传递,因为如果UserDetailsView进行了一些更新,我希望UserView进行更新。

问题是:
如果我在UserDetailsView中调用updateUserName() ,则UserDetailsView不会更新。
因为ViewModel是一个 class。而且只有@Published可以更新View

我知道一种可能的解决方案:
就是在UserDetailsViewModel中添加@Published var userName: String
然后在updateUserName()中更新此属性。

但我真的觉得它更像是一种解决方法而不是解决方案。
如果User有许多我想在UserDetailsViewModel中显示的属性怎么办?
那么我应该为每个创建@Published属性吗? 或者创建一个单独的@Published var publishedUser

有人能告诉我实现目标的最佳/正确方法是什么吗?
谢谢

在 SwiftUI 中,View 结构已经是一个视图 model(SwiftUI 区分视图结构数据以自动创建/更新/删除实际的 UIView),因此可以将 User 存储在 View 结构中的@State中,这就是它的用途。 您可以使用.task修饰符启动 async.network 下载,它在底层UIView出现时启动,在它消失时取消。 使用 object 会做更多的工作,如果操作不正确,您可能会泄漏。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM