コンポーネントがあり、ユーザーがコンポーネントをクリックすると、格納する値が追加されます。この方法を使用しようとしましたが、エラーが発生しました。
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」です
component
では、アプリの起動時にroute
やcontroller
のようにストアが自動的に挿入されません。これは、コンポーネントがより分離されていると考えられるためです。
以下は、ベストプラクティスとは見なされません。コンポーネントは、渡されたデータを使用する必要があり、その環境を認識しないでください。このケースを処理する最良の方法は、
sendAction
を使用して実行したいことをバブルアップし、コントローラー自体でstore
を使用してアクションを処理することです。
@ sly7_7の提案は良い提案であり、ストアにアクセスする必要がある場所から多くのコンポーネントがある場合、それはそれを行うための良い方法かもしれません。
store
にアクセスする別の方法は、store
が参照しているcomponent
を囲むcontroller
を取得することです。この場合、すべてのcontroller
にすでにcontroller
が参照されているため、これはどのstore
でも関係ありません。したがって、store
を取得するには、component
のtargetObject
を取得します。これは、controller
を囲むcomponent
です。 store
を取得します。
OlapApp.MeasureListItemComponent = Ember.Component.extend({
...
actions: {
add: function(measure) {
var store = this.get('targetObject.store');
...
}
}
});
実際の例については、 here を参照してください。
それが役に立てば幸い。
たとえば、子コンポーネントが1レベルだけネストされている場合、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()
});
以来Ember 2.1.0
export default Ember.Component.extend({
store: Ember.inject.service('store'),
});
before Ember 2.1.0-依存性注入方法
App.MyComponent = Ember.Component.extend({
store: Ember.computed(function() {
return this.get('container').lookup('store:main');
})
});
before 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
これを行う現在の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
};
これにより、すべてのコンポーネントにストアが追加されると考えています。
コンポーネントがそのような方法で使用されることを意図しているかどうかはわかりません。ただし、必要に応じて、イニシャライザを宣言し、ストアをすべてのコンポーネントに注入できると思います。
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
ストアは、依存性注入を使用して注入できます。
例
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}}