对于导航,我决定使用路由。 如果我有两个具有相同数据的视图,我就会遇到问题。 第一个是列表。 二是详细信息。 当第一屏上的数据更新时,视图也随之更新。 但是,如果用户查看第二个视图并且数据已更新,则第二个屏幕不会更新。
如何在数据更新时动态更新第二个视图?
我在主屏幕中使用 ObservedObject
@ObservedObject var router = Router<Views>()
WindowGroup {
NavigationStack(path: $router.paths){
RootScreenView()
.navigationDestination(for: Views.self){ destination in
ViewFactory.viewForDestination(destination)
}
}
}
这是我的ViewFactory
enum Views: Hashable {
case DetailView(order: OrderModel)
// Any cases
}
enum ViewFactory {
@MainActor
@ViewBuilder
static func viewForDestination(_ destination: Views) -> some View {
case .DetailView(let order):
DetailView(with: DetailViewModel(order: order))
}
}
}
}
final class Router<T: Hashable>: ObservableObject {
@Published var paths: [T] = []
func push(_ path: T) {
paths.append(path)
}
}
当其设计为去中心化时,集中路由是一个坏主意,即
navigationDestination
被设计为位于 View
数据结构层次结构中的任何位置。
此外,您不应该像
body
那样初始化 DetailViewModel(order: order)
中的对象,因为下次调用 body
时它将重新初始化,因此本质上这是内存泄漏。您需要使用 @State
作为视图数据,向下传递给子 View
,作为 let
表示只读,或 @Binding
表示读/写。每当数据发生变化时,都会调用body
,您可以使用新数据再次初始化子视图,并且 UI 将自动更新。因此,所有这些本质上已经是一个视图模型,如果您尝试在类中自己重新实现它,您将遇到一个又一个问题。