你如何为ember.js创建一个自定义适配器?(How do you create a custom adapter for ember.js?)

编程入门 行业动态 更新时间:2024-10-26 20:33:13
你如何为ember.js创建一个自定义适配器?(How do you create a custom adapter for ember.js?)

我正在计划使用ember.js,但是我的REST API并不完全与打包的REST适配器保持一致。 我想“重写”找到并能够把它自己的ajax。 我不喜欢如何找到一个余烬findAll检索我所有的文档没有分页选项,以便与其他查询参数一起使用会很有用 - 这就是为什么我想写我自己的Ajax。 我一直无法找到任何关于如何去做这件事的文档。

I'm planning on using ember.js, however my REST api doesn't exactly align with the packaged REST Adapter. I would like to "override" find and be able to put my own ajax in it. I dislike how an ember findAll retrieves all my documents with no options for pagination, so that along with other query parameters would be useful --which is why I want to write my own ajax. I've been unable to find any documentation on how I would go about doing this.

最满意答案

对于Ember数据

这是Ember Data 1.0 beta 9的最新版本。

扩展其中一个Ember数据适配器。 为了使其网站广泛:

App.ApplicationAdapter = DS.RESTAdapter.extend(....

为了使其具体模型:

App.FooAdapter = DS.RESTAdapter.extend(...

然后,您将定义您想要覆盖的实现。 您始终可以选择调用this._super并恢复到基本实现。 例如

App.NotesAdapter = DS.RESTAdapter.extend({ find: function(store, type, id) { id = "foo" + id; return this._super(store, type, id); } });

或者你可以完全覆盖实现:

App.NotesAdapter = DS.RESTAdapter.extend({ find: function(store, type, id) { // Do your thing here return this.ajax(this.buildURL(type.typeKey, id), 'GET'); }, findAll: function(store, type, sinceToken) { // Do your thing here var query; if (sinceToken) { query = { since: sinceToken }; } return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query }); }, findQuery: function(store, type, query) { // Do your thing here return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query }); }, findMany: function(store, type, ids, owner) { return this.ajax(this.buildURL(type.typeKey), 'GET', { data: { ids: ids } }); }, ..... });

要查看可以覆盖的完整api,请参阅: http : //emberjs.com/api/data/classes/DS.RESTAdapter.html

串行

通常更重要的是将滚动您自己的序列化器来进行数据的按摩,以适应您的休息端点。 以下是来自转换文档https://github.com/emberjs/data/blob/master/TRANSITION.md的一些有用信息。

简短版本是,一旦Ajax请求完成,所产生的有效负载就通过以下钩子发送:

如果原始请求是针对单个记录(如find / save),或者如果原始请求针对的是记录数组(如findAll / findQuery),则将有效内容发送到extractSingle, 这些方法的默认行为是将有效负载的顶层分成多个较小的记录。 这些较小的记录中的每一个都被发送到正常化,这可以一次对记录进行标准化。 最后,可以特定标准化特定类型的记录。 App.PostSerializer = DS.RESTSerializer.extend({ extractSingle: function(store, type, payload, id) { // massage this._super(store, type, payload, id); }, extractArray: function(store, type, payload) { // massage this._super(store, type, payload); }, normalize: function(type, hash, property) { // massage this._super(type, hash, property); } }); 当您的有效负载的顶层的组织方式与Ember数据所期望的不同时,请使用extractSingle和extractArray 如果有效载荷中的所有子哈希可以用相同的方式归一化,则使用no​​rmalize来规范化子哈希。 使用normalizeHash来规范化特定的子哈希值。 如果你重写extractSingle,extractArray或normalize,那么一定要调用超级,这样链的其余部分才会被调用。

滚动你自己的

App.FooAdapter = Ember.Object.extend({ find: function(id){ return $.getJSON('http://www.foolandia.com/foooo/' + id); } });

然后从你的路线,或任何地方

App.FooRoute = Ember.Route.extend({ model: function(){ var adapter = App.FooAdapter.create(); return adapter.find(1); } });

现在我亲自将注入适配器到路线上,以使我的生活更轻松:

App.initializer({ name: "fooAdapter", initialize: function (container, application) { application.register("my:manager", application.FooAdapter); application.inject("controller", "fooAdapter", "my:manager"); application.inject("route", "fooAdapter", "my:manager"); } });

然后在路线上,你可能会变得更懒,并且做到:

App.FooRoute = Ember.Route.extend({ model: function(){ return this.fooAdapter.find(1); } });

例如: http : //emberjs.jsbin.com/OxIDiVU/676/edit

您可以阅读有关Ember的更多信息(无Ember数据): Ember without Ember Data

For Ember Data

This is up to date as of Ember Data 1.0 beta 9.

Extend one of the Ember Data Adapters. To make it site wide:

App.ApplicationAdapter = DS.RESTAdapter.extend(....

To make it model specific:

App.FooAdapter = DS.RESTAdapter.extend(...

Then you will define the implementation you'd like to override. You always have the option to call this._super and revert to the base implementation. e.g.

App.NotesAdapter = DS.RESTAdapter.extend({ find: function(store, type, id) { id = "foo" + id; return this._super(store, type, id); } });

Or you can completely override the implementation:

App.NotesAdapter = DS.RESTAdapter.extend({ find: function(store, type, id) { // Do your thing here return this.ajax(this.buildURL(type.typeKey, id), 'GET'); }, findAll: function(store, type, sinceToken) { // Do your thing here var query; if (sinceToken) { query = { since: sinceToken }; } return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query }); }, findQuery: function(store, type, query) { // Do your thing here return this.ajax(this.buildURL(type.typeKey), 'GET', { data: query }); }, findMany: function(store, type, ids, owner) { return this.ajax(this.buildURL(type.typeKey), 'GET', { data: { ids: ids } }); }, ..... });

To see the complete api you can override see: http://emberjs.com/api/data/classes/DS.RESTAdapter.html

Serializer

Often more important will be rolling your own serializer for massaging the data to fit your rest endpoint. Here's some useful information from the transition document https://github.com/emberjs/data/blob/master/TRANSITION.md .

The short version is that once an Ajax request has completed, the resulting payload is sent through the following hooks:

The payload is sent to extractSingle if the original request was for a single record (like find/save) or extractArray if the original request was for an Array of records (like findAll/findQuery) The default behavior of those methods is to pull apart the top-level of the payload into multiple smaller records. Each of those smaller records is sent to normalize, which can do normalization a record at a time. Finally, specific types of records can be specially normalized. App.PostSerializer = DS.RESTSerializer.extend({ extractSingle: function(store, type, payload, id) { // massage this._super(store, type, payload, id); }, extractArray: function(store, type, payload) { // massage this._super(store, type, payload); }, normalize: function(type, hash, property) { // massage this._super(type, hash, property); } }); use extractSingle and extractArray when the top-level of your payload is organized differently than Ember Data expects use normalize to normalize sub-hashes if all sub-hashes in the payload can be normalized in the same way. use normalizeHash to normalize specific sub-hashes. make sure to call super if you override extractSingle, extractArray or normalize so the rest of the chain will get called.

Rolling your own

App.FooAdapter = Ember.Object.extend({ find: function(id){ return $.getJSON('http://www.foolandia.com/foooo/' + id); } });

Then from your route, or wherever

App.FooRoute = Ember.Route.extend({ model: function(){ var adapter = App.FooAdapter.create(); return adapter.find(1); } });

Now personally I'd inject the adapter onto the routes just to make my life easier:

App.initializer({ name: "fooAdapter", initialize: function (container, application) { application.register("my:manager", application.FooAdapter); application.inject("controller", "fooAdapter", "my:manager"); application.inject("route", "fooAdapter", "my:manager"); } });

Then on the route you could be lazier and do:

App.FooRoute = Ember.Route.extend({ model: function(){ return this.fooAdapter.find(1); } });

Example: http://emberjs.jsbin.com/OxIDiVU/676/edit

You can read more about Ember without Ember Data: Ember without Ember Data

更多推荐

本文发布于:2023-08-08 01:09:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1466771.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:自定义   适配器   创建一个   何为   ember

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!