1

I am rendering some model parameters in Ember, which should behave like a checkbox. Therefore the css class of the clicked element should change, to indicate the state (e.g. green when active). Currently all rendered elements change their class when only one was clicked. How can I only change the css class of the element that was really clicked ? I thought the .this will take care of that.

That is my view template:

  {{#each model as |attributes|}}
  {{#each attributes.identifiers as |identifier| }}
    <div class="col-element">
      <div class="checkelement {{state}}" {{action "includeToExport" identifier}}>
        <p>{{identifier}}</p>
      </div>
    </div>
  {{/each}}
{{/each}}

That the action in the controller:

includeToExport: function(identifier){
var state = this.get('state');
if (state == 'activated'){
  this.set('state','');
  // and do something with identifier
}
else {
  this.set('state', 'activated');
  // and do something with identifier
}},

An that the CSS:

.checkelement.activated {background-color:#4CAF50; }

Thanks for your help!

1 Answer 1

1

If you want to have a separate state for each item like that, one option is to create a component that will represent each identifier and move the state control there. You can think of it as moving all the code you have between {{#each}}...{{/each}} into its own component. This will allow you to encapsulate state control for each identifier:

{{#each model as |attributes|}}
  {{#each attributes.identifiers as |identifier| }}
    {{my-identifier identifier=identifier
                    includeToExportAction=(action "includeToExport")}}
  {{/each}}
{{/each}}

The component would look something like

// components/my-identifier
export default Ember.Component.extend({
  // passed in
  identifier: null,
  includeToExportAction: null,

  // local
  state: '', // <-- here you set the initial value for the state
  classNames: ['col-element'],

  actions: {
    setState() {
      // state-control is now local to each component
      // and thus unique for each identifier
      const state = this.get('state');
      if (state == 'activated'){
        this.set('state','');
      } else {
        this.set('state', 'activated')
      }

      // send the identifier and the updated state to the parent
      this.get('includeToExportAction')(
        this.get('state'),
        this.get('identifier')
      )
    }
  }
});

Template for component

// templates/components/my-identifier
<div class="checkelement {{state}}" {{action "setState"}}>
  <p>{{identifier}}</p>
</div>

And now your controller wouldn't need to set any state in includeToExport because it is now passed from the my-identifier component:

includeToExport(identifier, state){
  if (state == 'activated'){
    // do something with identifier
  }
  else {
    // do something with identifier
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.