1

Somehow I don't understand how to implement views which require a certain controller with ember.js. I'll try to explain the issue in which I run with an example:

Let's say I would like to build a view component which creates a simple todo list: It contains a textfield. Underneath of that field is a list of all todo items that have been entered so far. That view should have a controller which stores the todo items (since I don't have to push to store them persistent at that point).

I'd like the view to be usable in different places of the webapp (through my handlebars templates), so it should be independent of the route through which it is accessed.

My templates look like this:

<?xml version="1.0" encoding="utf-8"?>
<html>
  <head>
    <script src="../shared/libs/jquery-1.9.1.js"></script>
    <script src="../shared/libs/handlebars-1.0.0-rc.3.js"></script>
    <script src="../shared/libs/ember-1.0.0-rc.1.js"></script>
    <script src="todo.js"></script>
  </head>
  <body>
    <script type="text/x-handlebars" data-template-name="application">
      {{ view App.TodolistView }}
    </script>

    <script type="text/x-handlebars" data-template-name="todolistView">
      {{view App.CreateTodoTextField
        placeholder="Enter your todo here"
        size=100
        }}
       <ul>
        {{#each todo in controller}}
          <li>{{todo}}</li>
        {{/each}}
      </ul>
    </script>
  </body>
</html>

My App Logic looks like this:

window.App = Ember.Application.create();

App.TodolistView = Ember.View.extend({
  templateName: 'todolistView'
});

App.TodolistController = Ember.ArrayController.create({
  content: [],
  createItem: function(item) {
     this.pushObject(item);
  }
});

App.CreateTodoTextField = Ember.TextField.extend({
  insertNewline: function() {
    var value = this.get('value');
    if (value) {
      App.TodolistController.createItem(value);
      this.set('value', '');
    }
  }
});

I have two problems with that code:

When my TodolistView tries to access the controller with

{{#each todo in controller}}

it actually accesses the ApplicationController, not the TodolistController

Also calling

App.TodolistController.createItem(value);

looks like a bad idea to me: I.e. what if I would have two TodoListViews on one page? createItem should be rather called on the current instance of the TodolistController...

Probably I'm missing a core concept for defining views with ember.js...

laberning
  • 769
  • 7
  • 19
  • Solution for first problem: use needs. Refer this link:http://stackoverflow.com/questions/14388249/accessing-controllers-from-other-controllers – Dinesh Feb 22 '13 at 10:59
  • Actually the problem is you are not using the concept of the Router, which is a core concept of Ember. Have you omitted it intentionally? – mavilein Feb 22 '13 at 11:27
  • @mavilein My thought on this was: The router for Application will be created automatically and Todolist is supposed to be just a View component so I'm not sure whether it needs a Router. – laberning Feb 22 '13 at 12:16

2 Answers2

1
App.CreateTodoTextField = Ember.TextField.extend({
  insertNewline: function() {
    var value = this.get('value');
    if (value) {
      App.TodolistController.createItem(value);
      this.set('value', '');
    }
  }
});

Todoliscontroller can't be accessed like this. Only its instance can be accessed in the below way:

var controller = this.get('controller');
controller.controllerFor('todolist').createItem(value);
Dinesh
  • 111
  • 9
  • Thanks for the hint. Actually `controllerFor` is giving me a deprecation warning so I ended up using `this.get('controller').get('controllers.todolist').createItem(value); ` in combination with `needs` as mentioned above. I will post what worked for me below, but I'm still not sure if that is the way it is intended to be done. – laberning Feb 22 '13 at 12:19
1

Thanks for the hints, this is what, works for me, but I'm still not sure if this is the way its intended to be used:

HBS

<script type="text/x-handlebars" data-template-name="todolistView">
  {{view App.CreateTodoTextField
    placeholder="Enter your todo here"
    size=100}}
     <ul>
      {{#each todo in controllers.todolist}}
        <li>{{todo}}</li>
      {{/each}}
    </ul>
</script>

App.ApplicationController = Ember.Controller.extend({   
  needs: ['todolist']
});

JS

App.CreateTodoTextField = Ember.TextField.extend({
  insertNewline: function() {
    var value = this.get('value');
    if (value) {
      this.get('controller').get('controllers.todolist').createItem(value);
      this.set('value', '');
    }
  }
});
laberning
  • 769
  • 7
  • 19