this.store
属性存在于默认注入它的元素(控制器和路由)上,并且可能不应该使用,因为它跳过了 getter,这是 Ember 的重要组成部分。
在组件中访问它的正确方法(假设您注入了它)是通过:
this.get('store')
我从大量研究中发现,与商店的互动最好通过主要途径进行。
您可能希望(至少在大多数情况下)不是在主路由中而是在组件所在的控制器中访问存储数据,然后将数据传递给组件。
这有几个原因:
- Routes 的主要用途是获取数据并控制应用程序的路由机制,用户转换到的位置,转换发生的时间点以及转换的原因等。Routes 不应该控制显示哪些数据以及如何显示,只是如何/何时显示其获得。
- 控制器的主要用途是数据按摩、准备、转换等。这包括过滤数据、排序、提取子集等。
- 控制器数据在模板中直接可用,路由数据不可用。
Ember.Route 中的setupController()钩子实际上默认执行此操作。
这是在钩子中完成的默认操作:setupController()
set(controller, 'model', model);
因此,您的控制器默认可以访问模型,然后可以将其传递给组件。
通过这种方式,您可以清楚地将提取/获取/处理数据的逻辑与显示数据的逻辑分开。
我将事件侦听器附加到我的组件 HBS 文件中的按钮。其中一个按钮将触发两个级联但轻量级的 ajax 调用。最后一次 ajax 调用的响应将决定我是否应该创建记录。
在 Ember 中执行此操作的自然方法是将操作附加到您的按钮,该操作只会传播到控制器
// inside components/example.js
// ...
actions: {
myButtonAction() {
// call the controller action
this.get('controllerActionThatWasPassedIn')(/* pass any data if necessary */);
}
}
并让控制器执行实际的存储操作,然后在需要时将任何结果传递回组件。
// controllers/example.js
// ...
actions: {
handleData(someArgs) {
this.get('store)'.findSomething(someArgs).then((result) => {
this.set('result', result); // set the result which will automatically be passed down into the component
});
}
}
// templates/example.hbs
{{my-component result=result
controllerActionThatWasPassedIn=(action "handleData")
}}
在 Ember 中,这个概念称为Data down,Actions up。
像这样传递的动作被称为闭包动作,事实上,你也可以return
从它们那里得到这样的东西:
// inside components/example.js
// ...
actions: {
myButtonAction() {
// call the controller action
this.get('controllerActionThatWasPassedIn')(/* pass any data if necessary */)
.then((result) => {
// do stuff with result
});
}
}
如何将事件侦听器从路由附加到组件的 jquery 小部件?
注意:反模式
在 Ember 中并没有真正的自然方式来执行此操作,主要是因为路由和控制器是在渲染之前创建的。这就是为什么您不想在 Route 和 Controller 中执行此操作。
但是,如果您可能不需要 Controller 并且只想在 Route 中执行一些快速/小型 DOM 操作(请注意,这通常是一种反模式),您可以随时使用Ember Run Loop挂钩并安排一些操作在渲染之后发生:
export default Ember.Route.extend({
init() {
this._super(...arguments);
Ember.run.scheduleOnce('afterRender', () => {
$('.my-component').click(/* ... */)
});
}
});
或者您可以在渲染内容后直接在renderTemplate()挂钩中执行此操作:
renderTemplate() {
this.render();
$('.my-component').click(/* ... */); // Probably shouldn't do this though
}