How do I structure this to work?
I have Projects which have many notes. Notes are listed using an itemController. I need these notes to have an expanded view which can be toggled by the route (it's the show view for a note inside of the project). How can I get a route to toggle a specific note that's listed on the page to expand?
You can use the the official Ember Guides for help: http://emberjs.com/guides/. The example there is with a simple application with many posts (in your case projects) and each post has many comments (in your case notes). The only thing missing is the option to toggle a note, instead of open it permanently.
Using the Guide only, your router should look something like this:
App.Router.map(function () {
this.resource('project', {
path: '/project/:project_id'
}, function () {
this.resource('note', { path: '/note/:note_id' }, function () {});
});
});
App.ProjectController = Ember.ObjectController.extend({
toggle: function(note) {
var isOpen = !note.get('isOpen');
if (isOpen) {
this.transitionTo('note', note);
} else {
this.transitionTo('project', this.get('content'));
}
this.get('notes').forEach(function(note) {
note.set('isOpen', false);
});
note.set('isOpen', isOpen);
}
});
Then, your project template should list all the notes and provide a place to open a note and view it:
<script type="text/x-handlebars" data-template-name="project">
{{#each note in notes}}
<li>
<button type="button" {{action toggle note}}>
{{note.name}}
</button>
</li>
{{/each}}
{{outlet}}
</script>
<script type="text/x-handlebars" data-template-name="note">
{{description}}
</script>
To clarify things: ProjectController is an ObjectController with a content set to the currently opened project. ProjectController#notes is where all the notes for the currently loaded project will be. The project/note.handlebars will simply describe the note, as you desire it to be shown inside the project page.
Here is a working fiddle (with some boilerplate code added): http://jsfiddle.net/ZcspT/6/
EDIT:
Here is the version without routes (only the different parts):
App.Router.map(function () {
this.resource('project', {
path: '/project/:project_id'
});
});
App.NoteView = Ember.View.extend({
templateName: 'note',
content: null,
classNameBindings: ['content.isOpen::hidden']
});
App.ProjectController = Ember.ObjectController.extend({
toggle: function(note) {
var isOpen = !note.get('isOpen');
this.get('notes').forEach(function(note) {
note.set('isOpen', false);
});
note.set('isOpen', isOpen);
}
});
The templates:
<script type="text/x-handlebars" data-template-name="project">
{{#each note in notes}}
<li>
<a {{action toggle note}} href="#">{{note.name}}</a>
</li>
{{/each}}
<div id="noteSection">
{{#each note in notes}}
{{view App.NoteView contentBinding="note"}}
{{/each}}
</div>
</script>
The stylesheet:
.hidden {
display: none;
}
Example: http://jsfiddle.net/ZfWhc/1/