Access store from component

i have a component and when user click on component it add some value to store,i try to use this way but i get an error :

OlapApp.MeasureListItemComponent = Ember.Component.extend({
  tagName: 'li',
  isDisabled: false,
  attributeBindings: ['isDisabled:disabled'],
  classBindings: ['isDisabled:MeasureListItemDisabled'],

  actions: {
    add: function(measure) {
      var store = this.get('store');
      store.push('OlapApp.AxisModel', {
            uniqueName: measure.uniqueName,
            name: measure.name,
            hierarchyUniqueName: measure.hierarchyUniqueName,
            type: 'row',
            isMeasure: true,
            orderId: 1
      });
    }
  }
});

and this is error:

Uncaught TypeError: Cannot call method 'push' of undefined  MeasureListItemComponent.js:18

is it posible to push record to store from component? why i cant access to store ? my model name is 'AxisModel' and application namespace is 'OlapApp'


Since Ember v1.10, the store can be injected to components using initializers, see: http://emberjs.com/blog/2015/02/07/ember-1-10-0-released.html#toc_injected-properties:

export default Ember.Component.extend({
    store: Ember.inject.service()
});

In a component the store does not get injected automatically like in route's or controller's when your app starts. This is because components are thought to be more isolated.

What follows below is not considered a best practice. A component should use data passed into it and not know about it's environment. The best way to handle this case would be using sendAction to bubble up what you want to do, and handle the action with the store in the controller itself.

@sly7_7 suggestion is a good one, and if you have a lot of components from where you need access to the store then it might be a good way to do it.

Another approach to get to your store could be to get the store your component surrounding controller has reference to. In this case it doesn't matter which controller this is because every controller has already a reference to the store injected into it. So now to get to your store could be done by getting the component's targetObject which will be the controller surrounding the component and then get the store.

Example:

OlapApp.MeasureListItemComponent = Ember.Component.extend({
  ...
  actions: {
    add: function(measure) {
      var store = this.get('targetObject.store');
      ...
    }
  }
});

See here for a working example.

Hope it helps.

Update in response to your comment having nested components

If for example you child component is only nested one level then you could still refer to parent's targetObject using parentView:

App.ChildCompComponent = Ember.Component.extend({
  storeName: '',
  didInsertElement: function() {
    console.log(this.get('parentView.targetObject.store'));
    this.set('storeName', this.get('parentView.targetObject.store'));
  }
});

Updated example.