vendredi 16 février 2018

rendering templates with #link-to and dynamic segments

I have a simple app to show a list of clients, and a detail page for each specific client.

So basically, two URLs:

/clients/
/clients/:slug/

I've been having some trouble rendering the results from my Client model into a template, specifically when using the #link-to helper with dynamic segments.

I've found two methods for doing so, and while I can get them both to work, I don't know which one is the best and why.

Here is some (simplified) code from my app to explain.

// app/models/client.js
export default DS.Model.extend({
  name: DS.attr('string'),
  slug: DS.attr('string')
});

(my actual model is larger, but these are the only relevant fields)

and here are my routes:

// app/router.js
Router.map(function() {
  this.route('clients');
  this.route('client', { path: 'clients/:slug' });
});

NOTE: I didn't nest the routes, because I didn't want to use the nested template feature.

Here is the route for Clients, where I retrieve my list of clients

// app/routes/clients.js
export default Route.extend({
  model: function() {
    return this.get('store').findAll('client'); // fetch all Clients
  }
});

Finally, here is the route to fetch info for a single Client:

// app/routes/client.js
export default Route.extend({
  model: function(params) {
    return this.store.query('client',  {
      filter: { slug: params.slug } // fetch one specific client, by slug
    });
  }
});

Everything works fine up to here, but my issue starts when displaying the model data in the templates.

There are two "ways", which one is correct??

OPTION A:

//app/templates/clients.hbs
// list all clients using #each

   // pass the "client" object to generate my dynamic routes
    
  


Clicking on any of the generated links will render the client detail template, client.hbs

//app/templates/client.hbs
<h1>Client - </h1>

In this example, I can use model.name to render my model object. That's fine, until I refresh the page! Then the info returned by model.name is obliterated. Same thing if I try to visit the URL directly. I have to go back to /clients and click on the link again to see my client's name.

I then looked for another way to display my data, where the model information would survive a page reload.

OPTION B:

After much reading I found a suggestion to use the specific client slug/id as param for #link-to

// app/templates/clients.hbs
// list all clients using #each

   // specifically use the actual slug/id, and not the object
    
  


But... by passing client.slug instead of client as parameter to #link-to, I can no longer use model.name to display my data. It simply returns nothing!

//app/templates/client.hbs
<h1>Client - </h1> <-- model.name now returns nothing D:

However, using a loop DOES work for some reason:

//app/templates/client.hbs

  <h1>Client - </h1> <-- using loop even though I only have one record :(


But this feels like a hack, why would I need to use a loop to iterate through a single record?

So option B works, and the information is displayed correctly after a page reload, or a direct visit from the URL.

option A feels like the correct way, but reloading the page obliterates the data.

option B actually works and returns the data, but I have to use a loop to iterate through a single record.

I'm extremely confused, any clarification would be greatly appreciated.

Thanks in advance!




Aucun commentaire:

Enregistrer un commentaire