Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ember.js + Handlebars custom helper

I'm trying to implement a simple conditional statement in Handlebars that changes based on an attribute in my controller.

I've managed to come up with;

Handlebars.registerHelper("businessVerificationState", function(state, block) {
  var value = Ember.getPath(this, "state");
  if (value == state) {
    return block(this);
  }
});

App.businessController.business refers to a model object I've created and "state" is an attribute. Below is the template.

<script type="text/x-handlebars">
  {{#with App.businessController.business}}
    {{#exampleState "test1"}}
      <p>Test 1</p>
    {{/exampleState}}

    {{#exampleState "test2"}}
      <p>Test 2</p>
    {{/exampleState}}
 </script>

This all works swell. Except when my model attributes changes. From the console in webkit .. if I type ..

business.set("state", "test2"); for example - nothing changes.

If I use other standard handlebar statements like IF or UNLESS - the content changes based on when I update model attributes.

Obviously I'm doing something incredibly wrong and would appreciate any help.

like image 694
Jamsi Avatar asked Dec 21 '11 10:12

Jamsi


1 Answers

The easiest way to do this is to have a parent view that has a property bound to the controller value and child views that have the state names specified as a property. You can then define an isVisible computed property which will automatically toggle visibility of the child view depending on if it matches the current value bound in the parent view.

Your template could look like:

<script type="text/x-handlebars">
  {{#view Ember.View currentStateBinding="App.businessController.business.state"}}
    {{#view App.StateView stateName="test1"}}
      <p>Test 1</p>
    {{/view}}

    {{#view App.StateView stateName="test2"}}
      <p>Test 2</p>
    {{/view}}
  {{/view}}
</script>

And your JS code:

var App = Ember.Application.create();

App.businessController = Ember.Object.create({
    business: Ember.Object.create({
        state: 'test1'
    })
});

App.StateView = Ember.View.extend({
    isVisible: function() {
        return this.get('stateName') === this.getPath('parentView.currentState');
    }.property('parentView.currentState')
});

Here's a working jsFiddle example: http://jsfiddle.net/ebryn/QAxPU/

like image 99
ebryn Avatar answered Sep 24 '22 21:09

ebryn