lundi 22 août 2016

Dynamic navigation in Ember

I have a site with a layout that doesn't really change much, but the content within the layout changes. I can't find a really good way to do this in ember. Here is basically what I have so far:

templates/application.hbs

<header>
  <span class="title"></span>
</header>
<nav>
  
  
</nav>
<main>
  
</main>

app.js

/* Other app stuff... */

Ember.Route.reopen({
  defaultTitle: Ember.computed('routeName', function() {
    return this.get('routeName')
      .camelize()
      .capitalize()
      .replace(/\./g, ' - ')
      .replace(/([a-z])([A-Z])/g, '$1 $2');
  }),
  activate() {
    this._super(...arguments);
    this.updateTitle();
  },
  updateTitle: Ember.observer('title', function() {
    let title = this.get('title') || this.get('defaultTitle');
    this.controllerFor('application').set('title', title);
  }
});

This seems to work alright. If I want to override a title I can just add title: 'Much better name than the default' to the route.

However, it feels like an anti-pattern. Let's say I want to add a subtitle to certain routes, based on the model. First off, I would modify the template:

templates/application.hbs

<header>
  <span class="title"></span>
  <span class="subtitle"></span>
</header>
<!-- the rest is the same -->

Then, ideally on the route or controller I could just add an alias (e.g. subtitle: Ember.computed.alias('model.location')), but instead I have to create a new hook and manually set the new value when the model changes. This all just seems really clunky:

routes/photo.js

afterModel(model) {
  this.set('subtitle', model.get('location'));
}

app.js

activate() {
  /* same as before */
  this.updateSubtitle();
},
updateSubtitle: Ember.observer('subtitle', function() {
  this.controllerFor('application').set('subtitle', this.get('subtitle'));
}

It seems like application.hbs is the right place to put basic layout, but it feels like I'm doing something wrong. Updating the title should be simpler. I would imagine I could just do something like .

If I want to update the nav links dynamically, I'd run into a similar issue. It seems like I should just be able to do something like:

templates/application.js

<nav>
  
    
    
      
        
      
    
  
</nav>

Is there some kind of best-practice for dealing with dynamic navigation like this? In Aurelia, you can pretty easily do something like ${router.currentInstruction.config.title} or

<a repeat.for="route of router.navigation"
   href.bind="route.href"
   class="${route.isActive ? 'is-active' : ''}"
>${route.title}</a>

I haven't found anything like that with Ember, but it seems like it should be a relatively common paradigm.




Aucun commentaire:

Enregistrer un commentaire