从组件访问存储

我有一个组件,当用户点击组件时,它添加一些值来存储,我尝试使用这种方式,但我得到一个错误:

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 }); } } }); 

这是错误的:

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

推logging可以从组件中存储吗? 为什么我无法访问存储? 我的模型名称是“AxisModel”,应用程序名称空间是“OlapApp”

component ,当你的应用程序启动时,商店不会像routecontroller那样自动注入。 这是因为组件被认为是更孤立的。

下面的内容不被认为是最佳实践。 一个组件应该使用传递给它的数据,而不知道它的环境。 处理这种情况的最好方法是使用sendActionsendAction你想要做的事情,并用控制器本身的store来处理这个动作。

@ sly7_7build议是一个很好的build议,如果你有很多组件需要访问商店,那么这可能是一个很好的方法。

另一种到达store可能是将store周围的controller所参考的store 。 在这种情况下,哪个controller是无关紧要的,因为每个controller都已经注入了对该store的引用。 所以现在到达你的store可以通过获取componenttargetObject这将是围绕componentcontroller ,然后获得store

例:

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

在这里看到一个工作的例子。

希望能帮助到你。

更新回应你的评论有嵌套的组件

例如,如果您的子组件只嵌套一个级别,那么您仍然可以使用parentView引用父级的targetObject:

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

更新的例子 。

从Ember v1.10开始,商店可以使用初始化器注入组件,请参阅: 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() }); 

目前的做法似乎是使用初始值设定项。 非常类似于@ Sly7_7的答案。

要获得一个基本的模型使用:

  ember g initializer component-store-injector 

然后编辑这个:

 // app/initializers/component-store-injector.js export function initialize(container, application) { application.inject('component', 'store', 'store:main'); } export default { name: 'component-store-injector', initialize: initialize }; 

我相信这会将商店添加到所有组件中。

https://github.com/ember-cli/ember-cli-todos盗取;

自Ember 2.1.0以来

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

在Ember 2.1.0之前 – dependency injection的方式

 App.MyComponent = Ember.Component.extend({ store: Ember.computed(function() { return this.get('container').lookup('store:main'); }) }); 

在Ember 2.1.0之前 – 控制器方式

你可以通过控制器的属性传递商店:

 App.MyComponent = Ember.Component.extend({ value: null, store: null, tagName: "input", didInsertElement: function () { if (!this.get('store')) { throw 'MyComponent requires store for autocomplete feature. Inject as store=store' } } }); 

每个控制器上都有可用的存储。 所以在父视图中你可以包含如下的组件:

 {{view App.MyComponent store=store class="some-class" elementId="some-id" valueBinding="someValue" }} 

将属性传递给组件logging在这里

我不知道组件是否打算以这种方式使用。 但是,如果你想要的话,我想你可以声明一个初始化器,并将商店注入到所有组件中。

 Ember.onLoad('OlaApp', function(OlaApp) { OlapApp.initializer({ name: 'injectStoreIntoComponents', before: 'registerComponents', initialize: function(container, application){ container.register('store:main', App.Store); container.injection('component', 'store', 'store:main'); } }) }); 

这是一个人为的但工作的例子: http : //jsbin.com/AlIyUDo/6/edit

商店可以注入dependency injection的帮助。

 import Ember from 'ember'; export default Ember.Component.extend({ /** * */ store: Ember.inject.service(), /** * Initialize the component. */ init() { this.initialize(); this._super(); }, /** * Initialize the properties and prerequisites. */ initialize() { // Set the component properties this.todos().then((data) => { this.set('todoEntries', data); }); }, /** * Returns the todo entries. * * @returns {*|Promise|Promise.<T>} */ todos() { const store = this.get('store'); return store.findAll('todo'); }, }); 

还没有人提到的另一种方法是简单地将controller.store传递给组件

 {{my-awesome-component store=controller.store}}