Ember router exemple1

by gnepud

HTML

<script src="https://github.com/downloads/emberjs/ember.js/ember-latest.js"></script>
<script type="text/x-handlebars" data-template-name="application">
    
    <h1>The root template</h1>

    <!-- 
        some global widget which has its own content
        the collectionView has to have content set, but we also want to use the controller
        better way than repeating ourselves?
    -->
    {{view App.ProjectSelectorView 
        contentBinding="controllers.projectsController"
        controllerBinding="controllers.projectsController"
    }}
    
    <!-- these actions use the router -->
    <p>
        <a {{action goToHome}}>Home</a> <a {{action goToTasks}}>Tasks</a>
    </p>
    
    <div class="contents">
        {{outlet}}
    </div>
    
</script>

<script type="text/x-handlebars" data-template-name="home">
    {{#if controllers.projectsController.current}}
        <p>Dashboard for: {{controllers.projectsController.current.name}}</p>
    {{else}}
        <p>No project selected</p>
    {{/if}}
</script>


<script type="text/x-handlebars" data-template-name="tasks">
    {{#if controllers.projectsController.current}}
        <p>Tasks for: {{controllers.projectsController.current.name}}</p>
        <p>...</p>
    
    {{else}}
        <p>Select a project before viewing tasks.</p>
    {{/if}}
</script>

CSS

body {
  padding: 2em;   
}

h1 { font-size: 2em; }
h2 { font-size: 1.5em; }

a {  
  color: blue;
  cursor: pointer;
}

.contents {
   padding: 1em;
    border: 1px solid #CCC;
}

p {
    margin: 1em 0;
}

.info {
    padding-top: 1em;
}

.project-selector .is-current {
   background-color: #CCC;   
}

JavaScript

App = Em.Application.create();

App.ApplicationController = Em.Controller.extend();
App.ApplicationView       = Em.View.extend({ templateName: 'application' });

App.HomeController = Em.Controller.extend();
App.HomeView = Em.View.extend({templateName: 'home' });

App.TasksController = Em.ArrayController.extend();
App.TasksView = Em.View.extend({templateName: 'tasks' });

App.ProjectsController = Ember.ArrayController.extend({
    current: null,
    content: [
        Ember.Object.create({name: "Project X"}),
        Ember.Object.create({name: "Project Y"}),        
        Ember.Object.create({name: "Project Z"})
    ],
    
    // is it the controller's responsibility to respond to actions?
    setCurrent: function(e) {
        this.set("current", e.context);
    }
});

App.ProjectSelectorView = Ember.CollectionView.extend({
    tagName: "ul",
    classNames: ["project-selector"],
    itemViewClass: Ember.View.extend({
        classNameBindings: ["isCurrent"],
        
        // is it the controller's responsibility to respond to non-state actions?
        template: Ember.Handlebars.compile('<a {{action setCurrent target="controller" context="view.content"}}>{{view.content.name}}</a>'),

        // or is it the view's responsibility? (see click below)
        // template: Ember.Handlebars.compile('<a>{{view.content.name}}</a>'),

        // which then tells the controller something happened?
        // click: function(e) {
        //   e.preventDefault();
        //   this.setPath("controller.current", this.get("content"));
        // }

        
        // if we didn't use controller here we'd have to bind to parentView.content.current
        // which doesn't feel right, seems to be the controller's responsibility?
        isCurrent: function(){
            return this.getPath("controller.current") == this.get("content");
        }.property("controller.current"),

        // eg:
        
        // isCurrent: function(){
        //    return...