Erik
Erik

Reputation: 519

How to pass same object to multiple subviews?

For each element in my database I want to display a navigation link. The destination and the label of each element should get the same object passed. Now I'm creating for each view a new object. Therefore the UI is not consistent. How can I solve this problem and create exactly one viewModel for each element in the database and pass this to the two subviews?

ForEach(database.decks) { elem in 
    // looking for a solution like: let viewModel = ViewModel(deck: deck) and pass this
    NavigationLink (
        destination: DeckDetailView(viewModel: ViewModel(deck: elem)), // <----- this viewModel
        label: {
            ZStack(alignment: .topTrailing) {
                DeckItem(viewModel: ViewModel(deck: elem)) // <----- and this viewModel should be the same!
            }
        }
    )
}
                                               
                                            

Upvotes: 1

Views: 112

Answers (2)

Asperi
Asperi

Reputation: 257543

The good reuse design (and simplified view hierarchy, and update when needed explicitly) is to separate that link in standalone view for row, like

ForEach(database.decks) { elem in 
   DeckRowView(elem: elem)
}

and row

struct DeckRowView: View {
  @ObservedObject var vm: ViewModel

  init(elem: Deck) {
     self.vm = ViewModel(deck: elem)
  }

  var body: some View {
    NavigationLink (
        destination: DeckDetailView(viewModel: self.vm),
        label: {
            ZStack(alignment: .topTrailing) {
                DeckItem(viewModel: self.vm)
            }
        }
    )
  }
}

Upvotes: 1

Raja Kishan
Raja Kishan

Reputation: 18904

Possible solution. Create ViewModel object inside the ForEach and pass.

ForEach(database.decks) { elem in
    let vm = ViewModel(deck: elem) //<<-- here
    NavigationLink (
        destination: DeckDetailView(viewModel: vm), // <----- this viewModel
        label: {
            ZStack(alignment: .topTrailing) {
                DeckItem(viewModel: vm) // <----- and this viewModel should be the same!
            }
        }
    )
}
       

Upvotes: 0

Related Questions