如何将商店注入组件(使用本地存储适配器时)
how to inject a store into a component (when using localstorage adapter)
Ember docs 说定义这样的商店
MyApp.Store = DS.Store.extend();
如果您在组件中查找记录,这 doc 表示您可以像这样将商店注入组件
// inject the store into all components
App.inject('component', 'store', 'store:main');
但是,我正在使用我这样定义的本地存储适配器
App.ApplicationAdapter = DS.LSAdapter.extend({
命名空间:'my-namespace'
});
因此,我不知道如何按照上述说明将其注入组件(我需要在其中查找记录)。
按照 this SO answer 的说明,我尝试将 store
注入组件,方法是像 store=store
and/or store=controller.store
<li> {{my-component id=item.customid data=item.stats notes=item.notes store=store}} </li>
或
<li> {{my-component id=item.customid data=item.stats notes=item.notes store=controller.store}} </li>
当时的目标是能够在组件中的一个动作中做到这一点
var todo = this.get('store');
console.log(todo, "the new store");
todo.set('notes', bufferedTitle);
console.log(todo, "todo with notes set");
todo.save();
然而,todo.save();
总是触发
Uncaught TypeError: undefined is not a function
注意到我登录了商店了吗?这就是它显示的内容
Class {_backburner: Backburner, typeMaps: Object, recordArrayManager: Class, _pendingSave: Array[0], _pendingFetch: ember$data$lib$system$map$$Map…}
如果我检查它(通过打开树,此处未显示),它确实表明音符是通过 todo.set('notes', bufferedTitle);
设置的,但是,它没有任何其他属性我为索引路由定义的模型,这个对象没有 'save' 方法。因此,它似乎不是真正的商店,而只是一些次要对象。
我在尝试 this SO answer 时得到了相同的结果,它说要获取 targetObject
的存储
var todo = this.get('targetObject.store');
注意,我也试过这个,即将store设置为商品的store。
<li> {{my-component id=item.customid data=item.stats notes=item.notes store=item.store}} </li>
应该注意的是,如果我在组件中设置商店,我可以通过 {{store}}
在页面上打印商店,这给了我
<DS.Store:ember480>
但即使在应用程序代码中,我也无法在处理点击的操作中执行 var todo = this.get('store');
。
问题,使用 localStorage 适配器,我如何能够在组件中查找记录(目的是能够更改记录,然后再次保存)
注意,如果它很重要,我会像这样为 (index) 路由定义一个模型
App.Index = DS.Model.extend({
title: DS.attr('string'),
版本(遗憾的是我不知道我使用的 Ember 数据或适配器的版本)
Ember Inspector
1.7.0
Ember
1.9.1
Ember Data
<%= versionStamp %>
Handlebars
2.0.0
jQuery
1.10.2
更新以响应更多信息的请求
设置问题的代码很简单。
这是路由器(资源名称不好:)
App.Router.map(函数(){
this.resource('index', { 路径: '/'});
}
这是获取要在索引路由中使用的记录的路由
App.IndexRoute = Ember.Route.extend({
model: function{
var resource = this.store.find('index');
return resource;
}
});
我有一个 Index Controller,它对组件没有任何特别的作用(除非我应该在 Controller 上定义由组件事件触发的方法)
在 html 中,我使用车把将数据传递给组件
{{#each item in items}}
<li> {{my-component id=item.customid data=item.stats notes=item.notes store=store}}
{{/each}}
然后,在 components/my-component
中,我有一个标签,单击该标签应该会触发一个操作,让我可以编辑模型上的一个属性
<label> {{action "editTodo" on="doubleClick">{{notes}}</label>
点击会触发 App.MyComponent
中的这段代码,这会触发提示此问题的错误
var todo = this.get('store')
todo.set('notes', bufferedTitle);
todo.save()
根据this doc将商店注入组件的首选方法是为记录设置商店变量,例如
{{#each item in arrangedContent}}
<li> {{my-component store=item}} </li>
{{/each}}
然后在应用程序代码中,你可以做
var store = this.get('store');
store.set('todo', bufferedTitle);
恕我直言,将 store
注入组件并不是最好的主意...按照设计,组件应该是隔离的,不应该对 store
.
有任何了解
在您提供的文档中,它写道:一般来说,直接在组件中查找模型是一种反模式,您应该更愿意在包含组件的模板。
但是,如果您出于某种原因确实需要它,那么为什么不直接将变量 store
传递给组件呢?
{{my-component store=store}}
然后,您可以仅在真正需要的组件中从您的控制器传递 store
。
在您的所有组件中注入 store
很可能会导致您进行糟糕的设计(尽管起初看起来很诱人)。
虽然接受的答案对于简单的应用程序是明智的,但如果组件与 url 没有关系,则将商店注入组件是完全可以接受的,例如边栏内容或可配置的小部件在仪表板上。
在这种情况下,您可以使用初始化程序将商店注入组件。
但是,在测试中模仿初始化程序可能会很痛苦。我非常希望测试友好的优秀 Ember.inject API 能够扩展到服务之外并容纳商店。 (或者商店将简单地变成服务)。
这是 Ember 2 的更新答案:
Ember 数据的存储现在是 Service, and we can easily inject it into all Components via an Initializer,例如app/initializers/inject-store-into-components
:
export function initialize(application) {
application.inject('component', 'store', 'service:store');
}
export default {
name: 'inject-store-into-components',
initialize,
}
然后,在您的组件中,您可以使用 this.get('store')
访问商店。这避免了直接将商店作为参数传递给组件的需要,这需要在模板中使用大量样板。
Ember docs 说定义这样的商店
MyApp.Store = DS.Store.extend();
如果您在组件中查找记录,这 doc 表示您可以像这样将商店注入组件
// inject the store into all components
App.inject('component', 'store', 'store:main');
但是,我正在使用我这样定义的本地存储适配器
App.ApplicationAdapter = DS.LSAdapter.extend({ 命名空间:'my-namespace' });
因此,我不知道如何按照上述说明将其注入组件(我需要在其中查找记录)。
按照 this SO answer 的说明,我尝试将 store
注入组件,方法是像 store=store
and/or store=controller.store
<li> {{my-component id=item.customid data=item.stats notes=item.notes store=store}} </li>
或
<li> {{my-component id=item.customid data=item.stats notes=item.notes store=controller.store}} </li>
当时的目标是能够在组件中的一个动作中做到这一点
var todo = this.get('store');
console.log(todo, "the new store");
todo.set('notes', bufferedTitle);
console.log(todo, "todo with notes set");
todo.save();
然而,todo.save();
总是触发
Uncaught TypeError: undefined is not a function
注意到我登录了商店了吗?这就是它显示的内容
Class {_backburner: Backburner, typeMaps: Object, recordArrayManager: Class, _pendingSave: Array[0], _pendingFetch: ember$data$lib$system$map$$Map…}
如果我检查它(通过打开树,此处未显示),它确实表明音符是通过 todo.set('notes', bufferedTitle);
设置的,但是,它没有任何其他属性我为索引路由定义的模型,这个对象没有 'save' 方法。因此,它似乎不是真正的商店,而只是一些次要对象。
我在尝试 this SO answer 时得到了相同的结果,它说要获取 targetObject
的存储var todo = this.get('targetObject.store');
注意,我也试过这个,即将store设置为商品的store。
<li> {{my-component id=item.customid data=item.stats notes=item.notes store=item.store}} </li>
应该注意的是,如果我在组件中设置商店,我可以通过 {{store}}
在页面上打印商店,这给了我
<DS.Store:ember480>
但即使在应用程序代码中,我也无法在处理点击的操作中执行 var todo = this.get('store');
。
问题,使用 localStorage 适配器,我如何能够在组件中查找记录(目的是能够更改记录,然后再次保存)
注意,如果它很重要,我会像这样为 (index) 路由定义一个模型
App.Index = DS.Model.extend({
title: DS.attr('string'),
版本(遗憾的是我不知道我使用的 Ember 数据或适配器的版本)
Ember Inspector
1.7.0
Ember
1.9.1
Ember Data
<%= versionStamp %>
Handlebars
2.0.0
jQuery
1.10.2
更新以响应更多信息的请求
设置问题的代码很简单。 这是路由器(资源名称不好:) App.Router.map(函数(){ this.resource('index', { 路径: '/'}); }
这是获取要在索引路由中使用的记录的路由
App.IndexRoute = Ember.Route.extend({
model: function{
var resource = this.store.find('index');
return resource;
}
});
我有一个 Index Controller,它对组件没有任何特别的作用(除非我应该在 Controller 上定义由组件事件触发的方法)
在 html 中,我使用车把将数据传递给组件
{{#each item in items}}
<li> {{my-component id=item.customid data=item.stats notes=item.notes store=store}}
{{/each}}
然后,在 components/my-component
中,我有一个标签,单击该标签应该会触发一个操作,让我可以编辑模型上的一个属性
<label> {{action "editTodo" on="doubleClick">{{notes}}</label>
点击会触发 App.MyComponent
中的这段代码,这会触发提示此问题的错误
var todo = this.get('store')
todo.set('notes', bufferedTitle);
todo.save()
根据this doc将商店注入组件的首选方法是为记录设置商店变量,例如
{{#each item in arrangedContent}}
<li> {{my-component store=item}} </li>
{{/each}}
然后在应用程序代码中,你可以做
var store = this.get('store');
store.set('todo', bufferedTitle);
恕我直言,将 store
注入组件并不是最好的主意...按照设计,组件应该是隔离的,不应该对 store
.
在您提供的文档中,它写道:一般来说,直接在组件中查找模型是一种反模式,您应该更愿意在包含组件的模板。
但是,如果您出于某种原因确实需要它,那么为什么不直接将变量 store
传递给组件呢?
{{my-component store=store}}
然后,您可以仅在真正需要的组件中从您的控制器传递 store
。
在您的所有组件中注入 store
很可能会导致您进行糟糕的设计(尽管起初看起来很诱人)。
虽然接受的答案对于简单的应用程序是明智的,但如果组件与 url 没有关系,则将商店注入组件是完全可以接受的,例如边栏内容或可配置的小部件在仪表板上。
在这种情况下,您可以使用初始化程序将商店注入组件。
但是,在测试中模仿初始化程序可能会很痛苦。我非常希望测试友好的优秀 Ember.inject API 能够扩展到服务之外并容纳商店。 (或者商店将简单地变成服务)。
这是 Ember 2 的更新答案:
Ember 数据的存储现在是 Service, and we can easily inject it into all Components via an Initializer,例如app/initializers/inject-store-into-components
:
export function initialize(application) {
application.inject('component', 'store', 'service:store');
}
export default {
name: 'inject-store-into-components',
initialize,
}
然后,在您的组件中,您可以使用 this.get('store')
访问商店。这避免了直接将商店作为参数传递给组件的需要,这需要在模板中使用大量样板。