Should we still use Controllers and guidelines for new apps?


#1

Just starting out with Ember and trying to nail down some high level guide lines for our project that we are attempting to build in Ember. I’ve watched the excellent video by Erik Bryn here https://www.youtube.com/watch?v=U1HEzVWseng that covers a lot of aspects about what is being deprecated and how Components and Services should be used going forward.

I’ve searched for some Ember 2 tutorials (or tutorials that are relatively new) and show the way we should be developing new applications going forward and the only one I could find thus far (even the PluralSight ones seem to be outdated) is this tutorial https://www.ludu.co/course/ember but that tutorial uses Controllers and from what I could tell from Erik Bryn’s video is that we should not be using Controllers anymore.

Questions:

  1. Should we or should we not use Controllers for new Ember apps?
  2. Does anyone have any good guidelines / tutorials / videos (free or paid for) that covers best practices or guidelines for developing new Ember apps on version 1.13 with the aim of going to 2.0 as soon as it is released?

Thanks in advance


Discover Ember 2 - New online course!
#2

Is is not a guideline and I am still a beginner but I try to keep my Bloggr example up-to-date:

I think you still need controllers now because there are no routable components. You still need to store query parameters on the controller until they are moved back to the route. Also you still store models on the controller with controller.setProperties(models) like this:


#3

This is certainly something i’m also struggling with, seems to be a bad/hard time to start with Ember due to the vast changes upcoming in 2.0.

Trying to understand the correct approach for building a complex component driven app just seems beyond me at the moment :frowning: which is frustrating as I really want to use Ember for a new project but i’m hitting a brick wall.


#4

Phunky, I get your feeling. Things can get confusing during this transition period. The correct approach I believe is build as many components as you can. If there’s something you can’t do with components (for example, display it from a route, until we have routeable components) then use controllers and templates. In the future you will be able to easily convert them to a component.

Whenever you read “controller”, “view”, “template” in older guides, think that these are related (i.e. IndexController, IndexView, index.hbs). To map these concepts to the component world, “controller” and “view” are merged now into the component (Javascript part), and “template” the template: the UI part of the component. So we’d have an IndexComponent with its components/index.hbs.

Does this help? What else makes you feel you are hitting a brick wall?


#5

Sure, that makes sense but what i’m struggling to grasp is how to approach communication between components.

My usual approach for this is to have my components fire DOM customEvents which allows for complete separation of concerns between each component (Think Twitter FlightJS). They’re just reacting to events if they ever fire and this works well, but I can’t find the right way of doing this in EmberJS.

For example i’m currently building a tab component and which is broken down into ui-tabs, ui-tab, ui-panels and ui-panel component. Each may have various actions, but the one action they’ll certainly share is changing of current visible panel and i’m struggling to find how to handle this between ui-tabs and ui-panels as they’re not children or even siblings elements of each other.

app/components/ui-tabs/component.js

import Ember from 'ember';

export default Ember.Component.extend({
  classNames: 'ui-tabs',
  attributeBindings: [
    'id:data-tabs-id'
  ],

  actions: {
    unsetActive(){
      // Not ideal that i'm looping through, should really know which is active.
      this.get('childViews').forEach(function(tab){
        if( tab.isActive ){
          tab.toggleProperty('isActive');
        }
      });
    },

    setActive(tab){
      if( !tab.isActive ){
        tab.toggleProperty('isActive');
      }
    }
  },
});

app/components/ui-tab/component.js

import Ember from 'ember';

export default Ember.Component.extend({
  tagName: 'a',
  classNames: 'ui-tab',
  classNameBindings: [
    'isActive'
  ],

  attributeBindings: [
    'id:data-tab-id'
  ],

  click: function(e){
    var parent = this.get('parentView');
    parent.send('unsetActive');
    parent.send('setActive', this);
  },
});

I prefer to trigger actions on child components and have the top-most parent be the one that reacts to them usually. This works fine for ui-tabs, but i’ve not idea how to get ui-panels to also handle this without explicitly telling it about the tabs, which is something i’ve no clue how to do in a Ember way.


#6

My take on it: http://locks.svbtle.com/controllers-are-dead-long-life-controllers.


#7

I would use controllers as sparingly as possible. There are certain situations (at least in 2.0) in which you have no choice, like when using query params.

There’s a guide I wrote on my blog regarding the way forward, that probably addresses your questions: http://emberigniter.com/5-essential-ember-2.0-concepts/

As components are still not routable we also need controllers for that (although for the most part they are automatically generated behind a template).


#8

Good write-up. I think one thing that’s missing from a lot of the discussion is a ‘cookbook’ - e.g. demonstrating some simple/intermediate/advanced Controller usage and how that plays out in a Controller-free world.

(one thing I’ve struggled to find great documentation around is a Component for sorting a model via Ember.computed.sort - most of the existing stuff out there focuses heavily on using Controllers for this)


#9

@locks> nice article you wrote. It’s definitely helpful. I wonder if you could clarify what you mean when you say the component decorates the model? Is this part specific to the routable component or is it more generally applicable?

Especially, when it comes to arrays, with a typical scenario of a parent component that holds an array and instanciates a sub-component (through its template) for each item in the array, is it reasonable for the parent component to decorate each item? If it is, how would it do that without creating some ObjectProxy for each item, reimplementing something similar to ArrayController? If it is not, how can it deal with UI state for each item?

I posted a question on stack overflow on this subject, I was browsing around here as well.


#10

@spectras You can still decorate the model with things like arrangedContent and filteredContent like this:


#11

For what it’s worth, we have moved the old Guides Cookbook into the EmberWatch community project. It needs quite a bit of community love, however.


#12

OP’s question boils down to “Should I use controllers in a new Ember app? Or what is the best practice moving forward?”

Extending my August 8th and September 9th answers, I wanted to share an article I wrote a few weeks ago that precisely answers his question: Should we use controllers in Ember 2.0?