1
votes

I'm having a problem with Ember, although not too sure where the problem lies, whether it's within Handlebars or Ember component.

The issue is when a controller object context is passed in to an ember component, as an argument, the context is undefined. However, logging the object within the handlebars template, immediately preceding the component, shows the correct object (see index and components/component-button templates).

Templates

<script type="text/x-handlebars" data-template-name="application">
    <h1>Fiddling</h1>
    {{outlet}}
</script>

<script type="text/x-handlebars" data-template-name="index">
  {{#each sections}}
    {{#each buttons}}
        {{log 'source in template' ../source}}
        {{component-button source=../source options=this}}
    {{/each}}
  {{/each}}
</script>

<script type="text/x-handlebars" data-template-name="components/component-button">
    {{log 'source in component' source}}
    <button {{action 'options.action'}}>{{options.label}}</button>
</script>

Application

App = Ember.Application.create( {} );

/**
 * Component: Button
 */
App.ButtonComponent = Ember.Component.extend( {

  tagName: 'button',

  click: function click() {
    this.get( 'source' ).send( this.get( 'options.action' ) );
  }

} );

/**
 * Controller: Application
 */
App.IndexController = Ember.ObjectController.extend( {

  sections: Ember.A(),

  actions: {
    doSomething: function() {
      window.console.log( 'hooray!' );
    }
  },

  setup: function setup() {
    var source = this;

    var section = Ember.Object.create( {
      source: source,
      buttons: Ember.A( [
        Ember.Object.create( {
          label: 'Do something!',
          action: 'doSomething'
        } )
      ] )
    } );

    this.sections.pushObject( section );

  }.on( 'init' )

} );

App.IndexRoute = Ember.Route.extend( {
  model: function() {
      return { name: 'foo' };
  }
} );

See fiddle

1
You've got a couple of issues with naming conventions. Components names should be at least two words, dasherized. Your template is for a component called component-button so your component class should be named App.ComponentButtonComponent. Also, you don't need to use the click event in the component. Instead, when using an action you put the action method inside the actions hash. Ember currently doesn't bind dynamic action names well, so you'll want to pass the action name as an argument to a static action and fire it using this.send(). Or skip this all together and use an action target.Duncan Walker
I have the same problem, but my component is named correctly. @stefanpearson: Did changing the name solve your problem?PeterParameter

1 Answers

0
votes

Instead of referring to ../source in the each loop, do the following:

<script type="text/x-handlebars" data-template-name="index">
    {{#each section in sections}}
        {{#each section.buttons}}
            {{log 'source in template' section.source}}
            {{component-button source=section.source options=this}}
        {{/each}}
    {{/each}}
</script>

In the first each 'section' is defined, which can be used in nested each statements to refer to the section.