SwiftUI 如何不在列表中复制 ViewModel

SwiftUI How to not duplicate ViewModel in List

我有简单的 2 屏应用程序。第一个屏幕是 List,第二个是详细屏幕。

很明显我不需要 20 个详细屏幕,与 List 中的项目数相同,而只需要一个。

我需要将所选项目作为参数传递给详细屏幕的 ViewModel。我知道有两个选项可以实现这一点:

  1. 为每个 NavigationLink 创建新的 ViewModel(selectededItem: Item)
  2. 通过 EnvironmentObject 传递它,但这也是一个糟糕的解决方案,因为首先我需要一些方法 viewModel.selectedItem = item

我当前的实现。它复制视图模型,同样非常重要的问题是 - SwiftUI 是否为每个导航 link 以及视图模型创建新视图的副本?

List(viewModel.state.subCategory) { subCategory in
    HStack {
        NavigationLink(destination: {
            ProductsListBuilder.build(id: subCategory.id ?? -1)
        }, label: {
            Text(subCategory.title ?? "no name")
        })
    }
}

class ProductsListBuilder {
    static func build(id: Int) -> some View {
        let viewModel = ProductsViewModel(dataFetcher: RemoteDataProviderImpl.shared, productId: id)
        return ProductsListView(viewModel: viewModel)
    }
}

在这种情况下,您可以使用 LazyView:

struct LazyView<Content: View>: View {
    let build: () -> Content
    init(_ build: @autoclosure @escaping () -> Content) {
        self.build = build
    }
    var body: Content {
        build()
    }
}

它使得 build 仅在导航 link 实际打开时被调用:

NavigationLink(destination: LazyView(
    ProductsListBuilder.build(id: subCategory.id ?? -1)
), label: {
    Text(subCategory.title ?? "no name")
})