0

我创建了一个我面临的问题的简单示例。我有两个视图,ListView 和 EditView。ListView 正在观察包含用户名列表的 UsersViewModel(复数)。

使用 NavigationLink 我想展示一个可以编辑用户名的表单,这就是我感到困惑的地方。我创建了一个 UserViewModel(单数),我有 EditView 观察,但是当我尝试调用 EditView 从 ForEach 循环传递值时,我收到一个类型不匹配错误,因为我没有传递 UserViewModel。

也许我误解了可观察的对象。我想我可以更改编辑表单上的用户名,导航回列表视图,然后我会在列表中看到更改。

struct ListView: View {
    
    // Observe the Users View Model
    @ObservedObject var usersViewModel = UsersViewModel()
    
    var body: some View {
        
        NavigationView {
            List() {
                
                ForEach(usersViewModel.users) { user in

                    // FAILS with cannot converted "user" to expected type userViewModel
                    NavigationLink (destination: EditView(userViewModel: user)) {

                        Text("Hello \(user.name)")
                    }
                }
            }
            .navigationBarTitle("User List", displayMode: .inline)
            .onAppear(){
                usersViewModel.loadUsers()
            }

编辑视图

struct EditView: View {

  @ObservedObject var userViewModel: UserViewModel
     var body: some View {
         TextField("User Name", text: $userViewModel.user)
4

2 回答 2

0

我通过将 usersViewModel 传递给 editView 而不是 pawello2222 建议的 userViewModel 解决了这个问题,但显然您需要知道要编辑哪个元素。

所以我这样做了;

       let users = usersViewModel.users.enumerated().map({ $0 })
        
        NavigationView {
            List() {
                ForEach(users, id: \.element.id ) { index, user in

                    NavigationLink (destination: EditView(userViewModel: usersViewModel, index: index)) {
                        

这似乎很啰嗦,肯定必须枚举 viewModel 来为 EditView 提供要编辑的元素的索引不是正确的方法吗?

它有效,但我想知道正确的方法

于 2020-09-18T18:24:50.090 回答
0

无法将“用户”转换为预期类型 userViewModel

您可能想UserViewModel在两个视图中使用相同的(假设user是一个结构)。

更改您的 EditView 以期望usersViewModelinit 中的参数:

struct EditView: View {
  @ObservedObject var usersViewModel: UsersViewModel

并在父视图中传递它:

NavigationLink (destination: EditView(usersViewModel: usersViewModel))

否则,由于用户可能是一个结构,您将在子视图中修改用户的不同副本。

于 2020-09-18T09:35:18.073 回答