Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ember.js 从组件访问存储_Ember.js_Ember Data - Fatal编程技术网

Ember.js 从组件访问存储

Ember.js 从组件访问存储,ember.js,ember-data,Ember.js,Ember Data,我有一个组件,当用户单击该组件时,它会为存储添加一些值,我尝试使用这种方式,但出现了一个错误: OlapApp.MeasureListItemComponent = Ember.Component.extend({ tagName: 'li', isDisabled: false, attributeBindings: ['isDisabled:disabled'], classBindings: ['isDisabled:MeasureListItemDisabled'],

我有一个组件,当用户单击该组件时,它会为存储添加一些值,我尝试使用这种方式,但出现了一个错误:

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”

我不知道组件是否打算以这种方式使用。但是如果您愿意,我认为您可以声明一个初始值设定项并将存储注入所有组件

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

下面是一个精心设计但有效的示例:

组件中
应用程序启动时,商店不会像
路由
控制器
那样自动注入。这是因为组件被认为更加孤立

以下内容不被视为最佳实践。组件应该使用传递给它的数据,而不知道它的环境。处理这种情况的最佳方法是使用
sendAction
来冒泡您想要做的事情,并使用控制器本身中的
store
来处理该操作

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

另一种进入
商店
的方法是获取
商店
您的
组件
周围的
控制器
参考。在这种情况下,哪个
控制器
无关紧要,这是因为每个
控制器
都已经有一个对
存储
的引用注入其中。因此,现在可以通过获取
组件
目标对象来访问
存储
,该对象将是
组件周围的
控制器
,然后获取
存储

例子: 有关工作示例,请参见

希望能有帮助

更新以响应包含嵌套组件的注释 例如,如果子组件仅嵌套一个级别,则仍然可以使用
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 2.1.0以来

export default Ember.Component.extend({
  store: Ember.inject.service('store'),
});
余烬2.1.0之前-依赖项注入方式

App.MyComponent = Ember.Component.extend({

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

});
余烬2.1.0之前-控制器方式

App.MyComponent = Ember.Component.extend({

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

});
您可以从控制器传递存储为属性:

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"
}}

将属性传递给组件是有文档记录的

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

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

当前执行此操作的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');
    }
  })
});

自Ember v1.10版起,存储区就可以使用初始化器注入组件,请参见:


在依赖项注入的帮助下,可以注入存储

示例

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

});
从“余烬”导入余烬;
导出默认的Ember.Component.extend({
/**
*
*/
存储区:Ember.inject.service(),
/**
*初始化组件。
*/
init(){
这是初始化();
这个;
},
/**
*初始化属性和先决条件。
*/
初始化(){
//设置组件属性
this.todos().then((数据)=>{
此.set('todoEntries',数据);
});
},
/**
*返回todo条目。
*
*@returns{*| Promise | Promise.}
*/
待办事项(){
const store=this.get('store');
return store.findAll('todo');
},
});


好的一个,刚刚加了我的2美分,以防他只需要访问商店中的某些组件,但无论如何,这两种解决方案都会产生依赖性。我认为你的更好:)这个解决方案对你有效吗?我试过了,但是“store”属性没有出现在我的组件中。实际上我没有测试它。要么是完全错误,我应该删除,要么是初始化器出了问题。也许它应该在Ember.onLoad()钩子中声明。你能试试看,告诉我它是否工作得更好吗?
registerComponents
被重命名为
registerComponentLookup
store:main
不必注册,将在
App之后设置。ApplicationStore
是一个store类。所有这些东西现在都会抛出错误:)好吧,我不知道组件的targetObject。我一定要更新我对组件的知识。我很确定它确实是孤立的,在控制器上根本没有访问权限。组件中的sendAction怎么样?使用sendAction和使用event bubling将操作发送到具有store的路由或控制器?我有嵌套的组件,它不适合我。当我使用
console.log(this.get('targetObject.store'))登录时,
它说undefinedim试图以这种方式访问componet,我可以,但从视图看我不能。@MBehtemam似乎
sendAction
是解决这个问题的更好方法,因为组件理想情况下不应该直接摆弄
store
。我编辑了这个答案来解释这一点。@Marcello:oops错过了它-谢谢你的纠正这对我来说似乎是最好的做法,无可否认是一个灰烬新手+1尽管控制器已被弃用。但在我们获得可路由组件后,控制器将被弃用;假设可以使用的组件会被商店注入吗?@ MBehtemam,您可以考虑将这个标记为确认的解决方案,为什么它被称为代码>存储< /代码>,而不是代码>存储>代码>?这只是一个名称。您可以在组件中随意调用它(因此
store
也可以使用)。文档说明“使用Ember.inject.service()来注入一个与它作为属性注入的名称相同的服务”。所以我认为您需要执行“store:Ember.inject.service('storage')”@RonniEgeriis@J.Barca,你说得对。我想是储藏室