Search code examples
ember.jsember-router

EmberJS show router model in application.hbs


I am working with Ember.js, and I am trying to make my pages display the title of the page just below the navbar. To make this work I have tried to use model hook, and show it in the application.hbs file.

So far I have tried variations of this:

routes/contact.js

import Route from '@ember/routing/route';

export default class ContactRoute extends Route {
  model() {
    return 'Title of page';
  }
}

templates/application.hbs

<div>
  <NavBar />

  <div class="pageTitle">
    <h2>
      <p>{{@model}}</p>
    </h2>
  </div>

  <div class="body">
    {{outlet}}
  </div>
</div>

I've mostly tried to mess around with @model in application.hbs things like outlet.@model. But all of these attempts have resulted in empty titles or Template Compiler Errors. Does anyone have a solution for this? Preferably one that does not involve jquery?


Solution

  • If I understand correctly what you are trying to accomplish, it is a good use case for services.

    You need a couple parts. A service to keep track of the page title, and then you need to inject that service in the application controller so the template has access to the service, and also to inject the page title service in the routes so you can update the page title in the respective hooks.

    1. Page service
    import Service from '@ember/service';
    import { tracked } from '@glimmer/tracking';
    
    export default class extends Service {
      @tracked title = "Your App"
    }
    
    1. Application controller and template
    import Controller from '@ember/controller';
    import { inject as service } from '@ember/service';
    
    export default class ApplicationController extends Controller {
      @service pageTitle;
    }
    
    <h1>Welcome to {{this.pageTitle.title}}</h1>
    <br>
    <br>
    {{outlet}}
    <LinkTo @route="my-route">my route</LinkTo>
    <br>
    <br>
    
    1. MyRoute route updating the page title value in a model hook
    import Route from '@ember/routing/route';
    import { inject as service } from '@ember/service';
    
    export default class extends Route {
      @service pageTitle;
    
      model() {
        this.pageTitle.title = "My Route"
      }  
    }
    

    I have put it all together in an interactive Ember Twiddle demo.

    Hope this helps!