Cracker
Cracker

Reputation: 1768

'active' class added to link disappears when drilling down into the section

Templates

<script type="text/x-handlebars">
    <div>
        <ul id="navbar">
            <li>{{#linkTo 'projects'}}Projects{{/linkTo}}</li>
            <li>{{#linkTo 'about'}}About{{/linkTo}}</li>
        </ul>
    </div>
    {{outlet}}
</script>

<script type="text/x-handlebars" id="projects">
    <div class="l-wrap">
        <table class="list">
            <thead>
                <tr>
                    <th>Project Name</th>               
                </tr>
            </thead>
            <tbody>
                {{#each model}}
                <tr>
                    <td>{{#linkTo 'project' this}}{{name}}{{/linkTo}}</td>
                </tr>
                {{/each}}               
            </tbody>
        </table>        
    </div>
    <div>
    {{outlet}}
    </div>
</script>

<script type="text/x-handlebars" id="project">
    <p>Project Details for {{name}}</p>
    <p>Description: {{description}}</p>
</script>

Routes 1

  this.resource('projects', function() {
    this.resource('project', { path: ':project_id'});   
  });

Routes 2

  this.resource('projects');
  this.resource('project', { path: 'project/:project_id'});     

Problem

What I am trying to achieve is that when I click on Projects link it should display a list of projects. And when I click on the Project Name in the list, the list should disappear and the details of the clicked project should be displayed.

In Route 1 arrangement, the list of projects does not disappear. So I can't use it.

In Route 2 arrangement, the list of projects disappears and everything is as I expect except for one thing - the CSS 'active' class from Projects link disappears. I am still inside the Projects section, so I do not want the 'active' class to go away.

How can I achieve this?

Upvotes: 1

Views: 310

Answers (1)

CraigTeegarden
CraigTeegarden

Reputation: 8251

You can achieve your goal by using the index route of the projects route to show your initial list.

Use the same router as your Route 1:

App.Router.map(function(){
  this.resource('projects', function() {
    this.resource('project', { path: ':project_id'});   
  });
});

but configure the project template to only contain an outlet:

<script type="text/x-handlebars" id="projects">
    <p>Projects</p>
    {{outlet}}
</script>

Then move your original projects template into projects/index:

<script type="text/x-handlebars" id="projects/index">
    <p>Projects Index</p>
    <div class="l-wrap">
        <table class="list">
            <thead>
                <tr>
                    <th>Project Name</th>               
                </tr>
            </thead>
            <tbody>
                {{#each model}}
                <tr>
                    <td>{{#linkTo 'project' this}}{{name}}{{/linkTo}}</td>
                </tr>
                {{/each}}               
            </tbody>
        </table>        
    </div>

</script>

Now you link to projects you will enter projects.index, and when you link to a specific project it will replace the projects {{outlet}} with the project detail route.

JSBin example

Note: the reason the Route 2 does not keep the active class is that you have defined 2 parallel route paths, so when you switch to the other one the app thinks you have moved to a different area of the app. Ember's router uses the route nesting to determine which links to keep active.

Hint: enable logging of transitions to help know what routes you are entering

App = Ember.Application.create({
  LOG_TRANSITIONS: true
});

Upvotes: 1

Related Questions