我有一个组件,当用户点击组件时,它会添加一些值来存储,我尝试使用这种方式,但我收到一个错误:
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
将记录从组件中存储起来是否可行?为什么我不能进入商店? 我的模型名称是'AxisModel',应用程序名称空间是'OlapApp'
答案 0 :(得分:44)
自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()
});
答案 1 :(得分:43)
在component
中,商店不会像应用程序启动时route
或controller
那样自动注入。这是因为组件被认为更加孤立。
以下内容不被视为最佳做法。组件应该使用传递给它的数据而不知道它的环境。处理此案例的最佳方法是使用
sendAction
冒泡您想要做的事情,并使用控制器本身中的store
处理操作。
@ sly7_7建议很好,如果你有很多组件需要访问商店,那么这可能是一个很好的方法。
另一种访问store
的方法可能是store
component
周围controller
引用的controller
。在这种情况下,controller
这是什么并不重要,因为每个store
已经注入了store
。现在,通过获取component
targetObject
围绕controller
的{{1}}然后获取component
来获取store
即可。 {1}}。
OlapApp.MeasureListItemComponent = Ember.Component.extend({
...
actions: {
add: function(measure) {
var store = this.get('targetObject.store');
...
}
}
});
有关工作示例,请参阅here。
希望它有所帮助。
例如,如果您的子组件只嵌套了一个级别,那么您仍然可以使用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'));
}
});
更新了example。
答案 2 :(得分:14)
自Ember 2.1.0
export default Ember.Component.extend({
store: Ember.inject.service('store'),
});
在Ember 2.1.0之前的- 依赖注入方式
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"
}}
将属性传递给组件记录在here
答案 3 :(得分:13)
当前的ember-cli方法似乎是使用初始化程序。与@ 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
};
我相信这会将商店添加到所有组件中。
被盗答案 4 :(得分:7)
我不知道组件是否打算以这种方式使用。但是如果你愿意,我认为你可以声明一个初始化器并将商店注入所有组件。
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
答案 5 :(得分:6)
可以在依赖注入的帮助下注入商店。
示例强>
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');
},
});
答案 6 :(得分:4)
没有人提到的另一种方法是简单地将controller.store传递给组件,例如
{{my-awesome-component store=controller.store}}