Sarus
Sarus

Reputation: 3313

Ember.js: Access properties in "parent" controller when using {{render}} helper

I have the following setup:

| // IndexController contains array of search result objects
| IndexController  (ArrayController) 
|     //Contains a search result object with row data (array) and search metadata
|---> ResultController (ObjectController) 
|          // Contains just the row data which is rendered into a sortable table 
|--------> TableController (ArrayController)

The IndexController retrieves a list of objects from the server when the user initiates a search. Each object returned has some metadata about the search plus all the row data.

Each object is rendered using the {{#each}} helper in the Index template:

{{#each itemController="result"}}
    {{view App.ResultView}}
{{/each}}

The ResultView renders the metadata and then renders the actual table using the {{render}} helper like this:

<h2>{{pieceofMetaData}}</h2>
{{render "table" rows}}  

Since I specified the model (in this case the row data), the {{render}} helper creates an instance of the TableController for each result object. For example, if there are 3 result objects in the IndexController model then 3 TableControllers are created. The TableController is an ArrayController to take advantage of the sorting that an ArrayController can do for me. Inside the Table template I render the table itself:

  <table>
      <thead>
          <tr>
              <th>First Name</th>
              <th>Last Name</th>
          </tr>
      </thead>
      <tbody>   
          {{#each}}  <!-- Each row of data is rendered here -->
              <tr>
                  <td>{{firstName}}</td>
                  <td>{{lastName}}</td>
              </tr>
          {{/each}}
      </tbody>
   </table>

This works well but I have now run into an issue. I need to be able to access properties in the ResultController from inside the TableController. Basically the ResultController contains information about which columns are sortable. I cannot figure out how to access the parent ResultController from the child TableController.

I tried using needs: ['result'] inside of the 'TableController' but this just instantiates a new instance of the ResultController rather than giving me access to the actual parent.

I created a working jsbin below that sets up the code I described here.

http://emberjs.jsbin.com/paceqaki/7/edit

Any help or advice would be greatly appreciated!

Best,

Sarus

Upvotes: 4

Views: 1377

Answers (1)

ppcano
ppcano

Reputation: 2861

In your case, I would use a PersonTableComponent, check the example. Using the render helper is mostly used in a specific route context. I think, you are trying the get advantage of 'sortProperties', 'sortAscending' feature which is provided by Ember.SortableMixin, unfortunately this mixin seems only to work with ArrayProxy instances, so you would need to implement the sorting functionality in your component.

<script type="text/x-handlebars" data-template-name="components/person-table">  
    <h3>{{header}} )</h3>
     <table>
      <thead>
          <tr>
             <th {{action 'toggleSortFirstName' }}>First Name</th>
             <th {{action 'toggleSortLastName'}}>Last Name</th>
          </tr>
      </thead>
      <tbody>   
          {{#each sortedPeople}}
              <tr>
                  <td>{{firstName}}</td>
                  <td>{{lastName}}</td>
              </tr>
          {{/each}}
      </tbody>
   </table>
</script>



<script type="text/x-handlebars" data-template-name="index">  
    {{#each controller}}
        {{person-table header=header people=rows}}
    {{/each}}
</script>

App.PersonTableComponent = Ember.Component.extend({
  sortProperty: 'lastName',
  sortAscending: true,


  sortedPeople: Em.computed(function(){

    // define your sorting functionality
    return this.get('people').sort( function(item) {
      return -1;
    });

  }).property('people.@each', 'sortProperty', 'sortAscending'),

  actions: {
    toggleSortFirstName: function() {


      var sortValue = !this.get('firstNameSortValue');

      // save current sort state
      this.set('fistNameSortValue', sortValue);
      this.setProperties({sortProperty: 'firstName',
                          sortAscending: sortValue});

    },
    toggleSortLastName: function() {

      var sortValue = !this.get('lastNameSortValue');

      // save current sort state
      this.set('lastNameSortValue', sortValue);
      this.setProperties({sortProperty: 'lastName',
                          sortAscending: sortValue});
    }
  }
});

Look at the EmberJS guide sections Component and Rendering with helper.

Upvotes: 3

Related Questions