12
votes

I'm using a render helper inside a template, which renders a searchbox with a typeahead.

Essentially (code removed for brevity):

script(type='text/x-handlebars', data-template-name='index')
    {{render search}}

script(type='text/x-handlebars', data-template-name='search')
    {{view App.TaggableInput valueBinding="searchText"}}

Which gives me a SearchController separated from the IndexController.

Inside App.TaggableInput I'm grabbing searchController to do some checking on the keyUp event:

App.TaggableInput = Ember.TextField.extend({
    keyUp: function(e){
        var controller = this.get('controller');
        // Do stuff with the controller
    }
});

On Ember RC7, I can access the controller inside theview as you'd expect with this.get('controller').get('searchText').

However in Ember 1.0.0 this.get('controller') returns the view, and whatever I do I can't get searchController.

I can't find any related info on the ember website regarding what's changed or what I'm supposed to do... for now I'm sticking with RC7.

Any ideas? I've spent hours on it this morning and can't figure it out. Thanks.

UPDATE: Fixed!

I swapped out this.get('controller') for this.get('targetObject') and it works as before. Had a peruse through a recent commit in ember source to find it...

Thanks for your suggestions guys!

3
I have the same or a similar problem with 1.0.0. I guess that this.get('controller') gives you the implicilty created TaggableInputController and not the controller of your current route. But it's just a guess. - splattne
Ember.TextField used to extend View. Unless otherwise specified, a View's controller defaults to parentView.controller. As of Ember 1.0.0, Ember.TextField extends Component. A Component doesn't have a controller but rather has a targetObject. Thats why your solution works! - Jim Hall
I have an ember app with a text-input component subclassing the Ember.TextField one, and a select-input component that subclasses the Ember.Select class. However, in the select-input code I was able to access the controller with this.get('controller'), and in the text-input I needed to resort to the solution suggested in the UPDATE section above (this.get('targetObject')). I just wanted to comment about it here because it seems intereseting, and perhaps someone has some insight on the reasons for this. - Ernesto

3 Answers

5
votes

I guess that in your code

App.TaggableInput = Ember.TextField.extend({
    keyUp: function(e){
        var controller = this.get('controller');
        // Do stuff with the controller
    }
});

this line

 var controller = this.get('controller');

gets the controller associated to your (subview)

Try to use this line instead to access the route's controller:

 var controller = this.get('parentView.controller');
3
votes

Currently, the {{render}} helper takes 2 arguments, the first is the context, the second is the model. I recommend using this method and following the naming convention for the model's controller rather than setting the controller explicitly.

You can find the docs here: http://emberjs.com/guides/templates/rendering-with-helpers/#toc_the-code-render-code-helper

Accessing controllers from views was also being tracked in this discussion: https://github.com/emberjs/ember.js/issues/1712#issuecomment-31183940

0
votes

I think Ember has not changed its behaviour. I created a JSBin, where i managed to get the controller successfully.

What i did was creating a simple View and show it via {{render}} helper:

View:

App.FooView = Ember.TextField.extend({
  didInsertElement : function(){
    console.log(this.get("controller.constructor"));
    console.log(this.get("context.constructor"));
  }
});

Template:

{{render foo}}

And the first log statement showed an associated controller. Can you see any conceptual difference between my code and yours?