Ember.js 中 JSONAPIAdapter 的常用 API

栏目: JavaScript · 发布时间: 5年前

内容简介:目前 Emberjs 框架中使用 JSONAPIAdapter 为默认的 adapter,遵循 JSONAPI 的通信标准。目前本公司也默认使用的是此 adapter,所以一下 api 均是在此基础上。在 Ember Data 中,adapter 决定了如何向后端传递数据,提供了一些可以设置的接口,如 格式化请求的URL ,设置请求的header 等。在Emberjs 项目中,你可以设置顶层的

Ember JSONAPIAdapter

目前 Emberjs 框架中使用 JSONAPIAdapter 为默认的 adapter,遵循 JSONAPI 的通信标准。目前本公司也默认使用的是此 adapter,所以一下 api 均是在此基础上。

Adapter

在 Ember Data 中,adapter 决定了如何向后端传递数据,提供了一些可以设置的接口,如 格式化请求的URL ,设置请求的header 等。

在Emberjs 项目中,你可以设置顶层的 application/adapter.js 也可以在每个对应的 model (pods文件目录)的文件中创建针对单个 model 的adapter: modelName/adapter.js 。其中针对单个的 adapter.js 的优先权大于 application/adapter.js

URL Conventions

在 Ember Data 中默认使用的 DS.JSONAPIAdapter 中,如果要请求数据,可以在 route.js 中:

//    route.js
    model() {
        return this.get('store').findAll('post');
    }

上面的请求默认发向的 url 为 /posts ,也就是 JSONAPIAdapter 会默认为请求路径转换为复数。

提供了几个默认的请求:

Action HTTP Verb URL
GET /posts/123
GET /posts
PATCH /posts/123
POST /posts
DELETE /posts/123

请求过程中的复数转换

上文也提到了,在使用 JSONAPIAdapter 过程中,会进行复数的转换,包括对 modelName 也是,会进行转换,比如说 我们请求:

model(){
        return this.get('store').findAll('campus');
    }

JSONAPIAdapter 中会发送请求到 /campus 中,而寻找的 modelName 则是 campu 这显然不对,所以我们需要对特殊字词进行处理。

在 Ember Data 中使用的是 Ember Inflector 控制的复数转换。同样的,我们也需要对它进行设置(pods目录下):

// app/app.js
import  './modules/custom-inflector-rules';
//    app/modules/custom-inflector-rules.js
import Inflector from  'ember-inflector';

const inflector = Inflector.inflector;
 
// Tell the inflector that the plural of "campus" is "campuses"

inflector.irregular('campus', 'campuses');
 
// Modules must have an export, so we just export an empty object here

export  default {};

然后可以看到 请求发送的地址是 /campuses ,寻找的 modelName 也是 campus ,现在变成正常的了,数据也是可以正常显示的了。

properties

JSONAPIAdapter 提供了以下 porperties :

coalesceFindRequests

这有篇 文章 讲的这个属性的使用。下面是具体的使用:

我们先来看不设置此属性的时候:

//    后端返回的数据
'data': {
    'type':  'post',
    'id':  'idPost1',
    'attributes': {
        'title':  'post1',
        'content':  'post content'
    },
    'relationships': {
        'comments': {
            'data': [
                {
                'id':  1,
                'type':  'comment'
                },
                {
                'id':  2,
                'type':  'comment'
                }
            ]
        }
    }
}

这是post数据,当我们请求 post 数据的时候:

//    route.js
    model() {
        return  this.get('store').findRecord('post', 'idPost1');
    }

这时候可以看到 Ember Data 向 mirage 发送了两条请求(需要设置 { async: true } :

GET '/comments/1'
GET '/comments/2'

在将 coalesceFindRequests 属性设置为 true 的时候:

//    comment/adapter.js
import DS from  'ember-data';

export  default  DS.JSONAPIAdapter.extend({
    coalesceFindRequests:  true
});

可以看到现在只发送一条请求:

GET '/comments?filter[id]=1,2

defaultSerializer

defaultSerializer 这个属性设置使用的 serializer :

// post/adapter.js
import DS from  'ember-data';

export  default  DS.JSONAPIAdapter.extend({
    defaultSerializer: 'person'
});

将使用 person/serializer.js 中的设定对 post 进行设定。

需要注意的是此属性起作用的时候只有在此 model 的 serializer.js 以及 application/serializer.js 不存在的时候起作用(Pods目录)。

header

HTTP 消息头允许客户端和服务器通过 requestresponse 传递附加信息。某一些 API 会需要一些请求头,比如现在项目中使用到的 token,就是在每次进行请求的时候都携带这些请求头数据发送给后端服务。一般不在 init() 中设置header ,而是将其设为计算属性:

//    post/adapter.js
    headers:  computed(function () {
        return {
            'dataType':  'json',
            'contentType':  'application/json',
            'Content-Type':  'application/json',
            'Authorization':  `bearer selfToken`
        };
    })

请求头就被改变了。

这样就会在每次请求的时候携带本地的 token。

host

自定义主机,默认为本地作用域。

namespace

顾名思义,定义命名空间的.

//    adapter.js
    namespace: '/api/'

main method

pathForType(type)

格式化请求的路径:

//    router
    this.get('store').findAll('bjCompany');

如果不在 adapter.js 中进行设置,发送的请求是:

GET /bj-companies

也就是默认的转换为中划线以及进行复数化,如果不想进行中划线的转换:

//    bj-company/adapter.js
import DS from  'ember-data';
import { camelize } from  '@ember/string';
import { pluralize } from  'ember-inflector';
  
export  default  DS.JSONAPIAdapter.extend({
    pathForType(type) {
        let newType =  pluralize(camelize(type));
        return newType;    // newType: bjCompanies
    }
});

这样就达到了我们的目的.

buildURL

对URL 进行格式化,主要是进行复数化,可以通过复写 pathForType() 方法来达到重写 URL 的目的.

Record 相关

JSONAPIAdapter 提供的关于 record 的一些 hook,可以让你复写这些hook的逻辑来达到自己的目的,但是一般完全符合 JSONAPI 的数据规范后,这些基本不用重写.更多关于 Record 的部分请查询 相关API以及其他文档.

这里列举出来 JSONAPIAdapter 中涉及 record 的一些 hook:

generateIdForRecord()

用于生成在客户端生成的 Record 的id.返回的值将分配给 record 的 primaryKey .一般很少使用.比如:

//    bj-company/adapter.js
    generateIdForRecord(store, type, inputProperties) {
        return  343;
    }

新创建的 Record 的 id 就会变成 343(这里只是演示作用).

handleResponse()

返回 ajax 请求的数据或错误,如果想修改返回的数据规范或错误提示可以在此处进行修改.

很少使用,视具体项目情况而使用.

isInvalid()

验证如果是 422 错误,在 handleResponse() 返回一个 InvalidError() 的实例.

isSuccess()

请求返回成功,相应的status:

(status >=  200  && status <  300) || status ===  304;

shouldBackgroundReloadAll()

store使用此方法来确定在 store.findAll 使用缓存的记录数组解析后,存储是否应重新加载记录数组。

默认为 true .

设为 false 之后,带来的效果就是在本地两个页面同时显示同一 model 实例,从一页面跳转到另一页面的时候不会再次请求数据.

//    adapter.js
shouldBackgroundReloadAll(store, snapshotArray) {
  return false;
}

注意这个方法只有在store 返回缓存数据之后才被调用.也就是当第一次请求数据的时候此方法不会被执行.

This method is only checked by the store when the store is returning a cached record array.

shouldBackgroundReloadRecord()

与上面同理.

shouldReloadAll()

当返回 true 的时候会立刻再次请求数据,如果返回false,会立即使用本地缓存.具体使用实例可以查看 文档

shouldReloadRecord()

与上面同理.

sortQueryParams()

对查询的 参数 进行自定义排列,默认使用的是正序.

urlForCreateRecord()

为通过 store.createRecord() 创建的本地 record 在进行 record.save() 操作的时候构建 相应的 url ;

其他的api 也类似:

总结

JSONAPIAdapter 的相关API 的分析到此结束.

Written by FrankWang .

  1. this.get('store').findRecord('post',1)
  2. this.get('store').findAll('post')
  3. postRecord.save()
  4. this.get('store').createRecord('post').save()
  5. postRecord.destroyRecord()
  6. MDN 中查看

以上所述就是小编给大家介绍的《Ember.js 中 JSONAPIAdapter 的常用 API》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Beginning XML with DOM and Ajax

Beginning XML with DOM and Ajax

Sas Jacobs / Apress / 2006-06-05 / USD 39.99

Don't waste time on 1,000-page tomes full of syntax; this book is all you need to get ahead in XML development. Renowned web developer Sas Jacobs presents an essential guide to XML. Beginning XML with......一起来看看 《Beginning XML with DOM and Ajax》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

XML 在线格式化
XML 在线格式化

在线 XML 格式化压缩工具