1
votes

I have a small extract from my Ember app here. My page contains a number of views each containing different data each with their own controllers.

I want a search field (in index view) to go in one view which should "talk" to the stationList controller to update the content of the stationList view. This doesn't work. I get an error: TypeError: this.get(...).search is not a function

The logging outputs the name of the contoller I've asked it to use: App.StationListController

I added a second search form inside on the StationList View. This one works just fine. The logging this time outputs a dump of the StationListController object. So I am guessing that the other search form, despite my code (in SearchFormView): controllerBinding : 'App.StationListController', is not correctly setting the controller.

So I guess my question is why not?

How can I route the change on the form field in the one view to call a funciton on another view's controller?

Here's my code:

<script type="text/x-handlebars" data-template-name="application">
    {{outlet}}
</script>

<script type="text/x-handlebars" data-template-name="index">
    <div id="searchForm">search form view search: 
        {{#view App.SearchFormView}}
            {{view App.StationSearchField}}
        {{/view}}
    </div>

    <div id="stationList">{{render stationList}}</div>
</script>

<script type="text/x-handlebars" data-template-name="stationList">
    station list view search: {{view App.StationSearchField}}
    <ul>
        <li>List</li>
        <li>will</li>
        <li>go</li>
        <li>here</li>
    </ul>
    {{searchTerm}}
</script>

And

App = Ember.Application.create({})

App.SearchFormView = Ember.View.extend({
    init : function()
    {
        console.log("SearchFormView init", this.get('controller'))
    }
})

App.StationSearchField = Ember.TextField.extend({
    keyUp: function(event) {
        var searchTerm = this.value

        console.log("value",searchTerm,this.get('controller'))

        this.get('controller').search(searchTerm)
    }
})

App.StationListController = Ember.ArrayController.extend({
    content     : [],
    searchTerm  : null,

    search : function(term)
    {
        this.set("searchTerm",term)
        console.log("searching",term)
    }
});

Fiddle: http://jsfiddle.net/ianbale/8QbrK/14/

1

1 Answers

0
votes

I think the controllerBinding stuff is from the older version, I don't think that works anymore.

You can use controllerFor on get('controller') in the StationSearchField.

    this.get('controller').controllerFor('station_list').search(searchTerm)

But controllerFor is deprecated and may be removed. Depending on your application structure you use needs on the controller.

Another way which I am using, is to send a custom event from the View, which the Route then sends to the corresponding controller.

App.IndexRoute = Ember.Route.extend({
    events: {
      search: function(term) {
        controller = this.controllerFor('station_list')
        controller.search(term);
      }
    }
});

and dispatch a search event from view like so.

    this.get('controller').send('search', searchTerm);

The advantage of this method is you dispatch the same event from multiple places and it would get handled in the same way.

Here's the updated jsfiddle.