Question

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...

Was it helpful?

Solution 2

Got it working, I had to use a component. I had messed up the "value" part.

components/field-email.hbs :

<div {{bind-attr class=":field :email size"}}>
  <label {{bind-attr for=fieldname}}>{{label}}</label>
  {{input type="email" name=fieldname value=value placeholder=label}}
</div>

login.hbs :

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

What I get from this is that in order for attributes to be used in a component they have to be explicitly set when using the component. Once they are set, they are bound.

In my case, when the input value changes, the associated route property is updated as well which is pretty cool.

OTHER TIPS

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top