[英]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.