Passing variables to handlebars partials in Ember.js

Jim picture Jim · May 7, 2014 · Viewed 7.6k times · Source

What I want to do should be fairly simple. I want to pass variables to partials for reusability.

I want to do something like this :

<form {{action login content on="submit"}}>
  <fieldset>
    {{partial 'components/field-email' label="Email" fieldname="email" size="full"}}
    [...]
  </fieldset>
</form>

Instead of doing this :

<form {{action login content on="submit"}}>
  <fieldset>
    <div {{bind-attr class=":field :email size"}}>
      <label {{bind-attr for=fieldname}}>{{label}}</label>
      {{input type="email" id=fieldname name=fieldname valueBinding="email" placeholder=label}}
    </div>
    [...]
  </fieldset>
</form>

coming from Rails, I expected this to just work, but it seems I can't (don't know how to) pass variables to a partial. I looked at all the ways to "include a template part":

  • partial
  • view
  • render

The thing that worked for me is using a View. But I thinks it's overkill. I just want separate sub-templates for reusability and readability, no context change or specifying a controller needed here.

Edit:

I also tried to use this partial as a component :

{{field-email type="email" id="email" name="email" valueBinding="email" placeholder=label size="full"}}

Which works for everything except the valueBinding.

I guess it's also worth mentioning that I have a route setup with an action that calls login on my AuthController :

App.LoginRoute = Ember.Route.extend
  model: -> Ember.Object.create()
  setupController: (controller, model) ->
    controller.set 'content', model
    controller.set "errorMsg", ""
  actions:
    login: ->
      log.info "Logging in..."
      @controllerFor("auth").login @

This whole thing works if all the markup is in the login template but fails if I try to break it up with partials, components and such.

There has to be something that I didn't see...

Answer

ppcano picture ppcano · May 7, 2014

You should use a component in this case.

If you setup your template correctly (components/field-email), you can use on this way:

{{field-email label="Email" fieldname="email" size="full"}}

You could setup the html component properties, if you define the component. Based on your example, it could be:

App.FieldEmailComponent = Ember.Component.extend({
  classNames: ['size'],
  classNameBindings: ['email', 'field'],
  field: null,
  email: null

});

Example: http://emberjs.jsbin.com/hisug/1/edit