使用ember数据url模板的EmberJS自定义适配器
EmberJS Custom adapter using ember-data-url-templates
我再次为EmberJS中的适配器而苦苦挣扎。这一次,它与使用ember数据url模板的嵌套api请求有关。
首先,相关代码:
// /app/application/adapter.js
import DS from 'ember-data';
var AppAdapter = DS.JSONAPIAdapter.extend({
host: 'http://coursedev.api'
});
export default AppAdapter;
// /app/router.js
import Ember from 'ember';
import config from './config/environment';
const Router = Ember.Router.extend({
location: config.locationType
});
Router.map(function() {
this.route('courses');
this.route('course', { path: '/course/:course_id' });
this.route('lesson', { path: '/course/:course_id/lesson/:lesson_id' });
});
export default Router;
// app/course/model.js
import DS from 'ember-data';
export default DS.Model.extend({
order: DS.attr('number'),
title: DS.attr('string'),
body: DS.attr('string'),
lessons: DS.hasMany('lesson')
});
// app/lesson/model.js
import DS from 'ember-data';
export default DS.Model.extend({
order: DS.attr('number'),
title: DS.attr('string'),
body: DS.attr('string'),
course: DS.belongsTo('course'),
questions: DS.hasMany('question')
});
// app/lesson/adapter.js
import AppAdapter from '../application/adapter';
import UrlTemplates from "ember-data-url-templates";
export default AppAdapter.extend(UrlTemplates, {
urlTemplate: '{+host}/courses/{courseId}/lesson/{id}',
urlSegments: {
host: function () {
return this.get('host');
},
courseId: function(type, id, snapshot, query) {
return snapshot.belongsTo('course', { id: true });
}
}
});
// app/lesson/route.js
import Ember from 'ember';
export default Ember.Route.extend({
model(params) {
return this.store.findRecord('lesson', params.lesson_id );
}
});
// app/lesson/template.hbs
<h1>{{model.title}}</h1>
{{model.body}}
<br>
This lesson is part of {{#link-to 'course' model.course.id}}{{model.course.title}}{{/link-to}}
其理念是,一门课程由几个问题组成。api以嵌套的方式提供数据:
/courses > all the courses
/courses/{courseId} > detailed course info
/courses/{courseId}/lesson/{lessonId}/ > detailed lesson info
当在应用程序中"内部"导航而不是直接访问路由时,此代码运行良好。然后显示相应的标题、正文以及它所属的课程。但是,当直接导航到/courses/1/session/3时,适配器无法从快照中找到courseId,因为请求指向http://coursedev.api/courses//lesson/3.请注意缺少课程ID。此URL不存在,因为应该提供courseId。
我的第一个问题是,上面的方法处理嵌套的api url是否正确?如果是这样的话,那么应该如何收集courseId来对api进行适当的请求?
再次表示衷心的感谢!
好的,是的。我理解你的困惑。
当你已经有一节课加载了一门课程时,你所拥有的一切都很好。当直接导航到课程时,您需要从url中获取课程id,并以某种方式将其传递给适配器。对此,显然没有更好的解决方案;以下是一些选项,按偏好排序:
1.不要在API中使用嵌套的URL
如果您可以控制API的结构,我建议您不要以这种方式嵌套资源。以嵌套方式加载集合子资源(例如/courses/:course_id/lessons
)可能是有意义的,但/lessions/:lesson_id
比/courses/:course_id/lessons/:lesson_id
更可取。
然而,您可能无法控制您的API,这正是创建ember-data-url-templates的原因。。。
2.使用queryRecord
您可以使用queryRecord
加载一条记录并传递更多信息,而不仅仅是id。
// adapter
export default AppAdapter.extend(UrlTemplates, {
queryRecordUrlTemplate: '{+host}/courses/{course_id}/lesson/{lesson_id}',
});
// route
this.store.queryRecord('lesson', params);
3.使用服务
将信息传递给适配器的另一种方法是使用服务。这种方法看起来不适合你的情况,但我会把它包括在这里,以防它对另一个类似的问题有所帮助。我经常使用服务来保存常规会话信息(例如用户id)。以下是如何使用会话服务完成与上面相同的事情:
// adapter
export default AppAdapter.extend(UrlTemplates, {
session: Ember.inject.service(),
findUrlTemplate: '{+host}/courses/{courseId}/lesson/{id}',
urlSegments: {
courseId() { return this.get('session.courseId'); },
},
});
// somewhere else in your application
this.set('session.courseId', params.course_id);
// route model hook
this.store.findRecord('lesson', params.lesson_id);
我希望这能有所帮助:)
幻灯片:http://www.slideshare.net/RyanMHarrison/nest-v-flat-with-emberdata
视频:https://www.youtube.com/watch?v=DjAMSjFPLW8
详细说明使用buildURL和@amil的附加成员数据url模板进行嵌套的选项。
- 建议避免服务
- 使用快照而不是查询(与其他存储方法一起使用,包括
findAll()
和findRecord()
)。YMMV - 如果您只需要只读访问并且API是HATEOAS样式,则链接是一个选项
- Dojo不解析自定义小部件的模板html中的小部件声明性
- 在自定义mean.io包中使用angular-chart.js作为依赖项
- jQuery自定义验证比较多个输入的序列
- 从HTTPGET返回一个自定义对象列表,以便在Angular 2应用程序中使用
- 在wordpress一定时间后更改自定义字段
- 表达式引擎扩展开发-向呈现的条目添加自定义javascript
- 自定义函数中的光标位置
- 用于检查数组中是否存在元素的javascript自定义方法
- 绑定时将Parsley minlength消息作为选项传递时,未对其进行自定义
- Meteor-添加用户自定义字段的方法不起作用
- 自定义表单验证和提交
- jQuery工具验证器自定义效果-添加&消除影响
- 可以't计算自定义谷歌地图的js
- 谷歌水印未显示在自定义搜索框中
- EmberJS/HandlebarsJS的自定义for-loop助手
- 使用ember数据url模板的EmberJS自定义适配器
- EmberJS:自定义相关模型的REST URL
- 如何在emberjs视图上运行自定义JavaScript
- Emberjs-扩展自定义组件;无法正确添加到容器视图中
- EmberJS自定义文本框视图ID-suffix