Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind handlebars to arbitrary property?

I'm trying make a binding to property of the controller but the property name is itself stored as another property of the controller. I need to bind to a property without knowing the property name at design-time. Is this possible? Or what is the better way to do things?

I'm making a view that displays the content of an ArrayController as a table. The ArrayController has a list a property names it wants displayed (columnsMeta). In the template, I look through all the items in the controller then loop through all the columns and want to get and bind the column value.

One attempt is to make a handlebars helper to get the property value:

Ember.Handlebars.registerBoundHelper('getProperty', function(property, obj) {
    return obj.get(property);
});

and then in the template, pass the property name and object to the helper:

{{#each row in controller}}
    <tr>
    {{#each col in columnsMeta}}
        <td>{{getProperty col.property row}}</td>
    {{/each}}
    </tr>
{{/each}}

This outputs the correct text in the table and each piece of text is surrounded with metamorph tags but when I change the values of the models' properties, the template does not update, it appears not to actually be bound.

These notations also do not work:

{{row.[col.property]}}
{{row.[(col.property)]}}

The the property by the name of "col.property" doesn't exist and nothing is printed.



I see that the ember-table project uses contentDidChange and creates a computed property in the view to feed the template the cell contents. Table Cell View in ember-table

But is that really necessary? Is there less heavy way? Do I just have my syntax wrong?

thanks!

like image 979
Noland Avatar asked Nov 01 '22 06:11

Noland


1 Answers

One solution may be to move the logic out of a registerBoundHelper and into an ObjectController

Controller Code

App.ColController = Ember.ObjectController.extend({
  needs: ["row"],
  getProperty: function () {
      return this.get('controllers.row.' + this.get('property'));
   }.property('controllers.row.foo', 'controllers.row.bar'),  //this solution may not work if one does not have a finite known set of properties to observe    
});

View Code:

<script type="text/x-handlebars" data-template-name="row">
   {{#each row in controller}}
     <tr>
      {{#each col in columnsMeta}}
         {{render 'col' col}}
      {{/each}}
      </tr>
  {{/each}}
</script>

<script type="text/x-handlebars" data-template-name="col">
   <td>{{getProperty}}</td>
</script>
like image 115
TrevTheDev Avatar answered Dec 23 '22 23:12

TrevTheDev