从组件访问存储

MBe*_*mam 49 ember.js ember-data

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

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
      });
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

这是错误的:

Uncaught TypeError: Cannot call method 'push' of undefined  MeasureListItemComponent.js:18
Run Code Online (Sandbox Code Playgroud)

将记录从组件中存储起来是否可行?为什么我不能进入商店?我的模型名称是'AxisModel',应用程序命名空间是'OlapApp'

Jac*_*gen 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()
});
Run Code Online (Sandbox Code Playgroud)

  • @ J.Barca,你是对的.我认为存储是Ember 1.10发布时商店的别名.现在我只使用`store:Ember.inject.service()`. (3认同)

int*_*xel 43

在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');
      ...
    }
  }
});
Run Code Online (Sandbox Code Playgroud)

请看这里的工作示例.

希望能帮助到你.

更新以响应您的嵌套组件的评论

例如,如果您的子组件仅嵌套一个级别,那么您仍然可以使用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'));
  }
});
Run Code Online (Sandbox Code Playgroud)

更新的例子.


Jan*_*šek 14

自Ember 2.1.0起

export default Ember.Component.extend({
  store: Ember.inject.service('store'),
});
Run Code Online (Sandbox Code Playgroud)

在Ember 2.1.0之前 - 依赖注入方式

App.MyComponent = Ember.Component.extend({

  store: Ember.computed(function() {
     return this.get('container').lookup('store:main');
  })

});
Run Code Online (Sandbox Code Playgroud)

在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'
     }
  }

});
Run Code Online (Sandbox Code Playgroud)

每个控制器都有商店.因此在父视图中,您可以包含如下组件:

{{view App.MyComponent
    store=store
    class="some-class"
    elementId="some-id"
    valueBinding="someValue"
}}
Run Code Online (Sandbox Code Playgroud)

此处记录了将属性传递给组件


jom*_*odo 13

当前的ember-cli方法似乎是使用初始化程序.与@ Sly7_7答案非常相似.

要获得基本模型使用:

  ember g initializer component-store-injector
Run Code Online (Sandbox Code Playgroud)

然后编辑为:

// 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
};
Run Code Online (Sandbox Code Playgroud)

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

从https://github.com/ember-cli/ember-cli-todos窃取


sly*_*7_7 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');
    }
  })
});
Run Code Online (Sandbox Code Playgroud)

这是一个人为但又有效的例子:http://jsbin.com/AlIyUDo/6/edit

  • `registerComponents`被重命名为`registerComponentLookup`也是`store:main`不需要注册,并且在`App.ApplicationStore`是商店类之后将被设置.所有这些事情现在抛出错误:) (2认同)

use*_*545 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');
  },

});
Run Code Online (Sandbox Code Playgroud)