Javascript Ember CLI-重新适应第三方API
我可以使用ic.ajax将数据输入我的应用程序,但似乎我应该使用RESTAdapter。解释是如此简单,以至于我不知道在各种情况下该怎么办。这是我认为应该起作用的:(并与fixture、本地express服务器和http mock一起使用) 我将以tumblr为例,因为它通常是友好的API 路由器.js routes/post.js 所以,据我所知-Javascript Ember CLI-重新适应第三方API,javascript,ember.js,ember-data,tumblr,ember-cli,Javascript,Ember.js,Ember Data,Tumblr,Ember Cli,我可以使用ic.ajax将数据输入我的应用程序,但似乎我应该使用RESTAdapter。解释是如此简单,以至于我不知道在各种情况下该怎么办。这是我认为应该起作用的:(并与fixture、本地express服务器和http mock一起使用) 我将以tumblr为例,因为它通常是友好的API 路由器.js routes/post.js 所以,据我所知-find()是一个神奇的ajax调用。。。但是如果我想指定jsonp或其他什么呢 适配器/post.js 这有点奇怪,因为tumblr端点太长了——
find()
是一个神奇的ajax调用。。。但是如果我想指定jsonp或其他什么呢
适配器/post.js
这有点奇怪,因为tumblr端点太长了——我觉得应该是http://api.tumblr.com
也许还有另一种方法来指定其他内容。。。或者它只是不知怎的知道。。。非常困惑。。。似乎名称空间:“v2”是该选项的用途
模板/帖子.hbs
然后在这之上-我得到了一个似乎是cors问题的gethttp://api.tumblr.com/v2/blog/feministlibraryonwheels.tumblr.com/posts?api_key=UbB4p0GxqNa6wUa8VwpIdqtywjIiA6vljZXyI9wkx9hnQnAFyk/posts 401(未授权)
而且它并不是真的隐藏着。。。[
许多快速教程(以及现实世界中的RestaAdapter)与real API之间缺少的链接是什么???任何方向都将非常感谢。
此外,这里还有一些ic.ajax()
尝试。有效负载到达控制台-但在尝试将数据放入模板时,它变得模糊
import Ember from 'ember';
import ajax from 'ic-ajax';
export default Ember.Route.extend({
model: function() {
var libraryData = ajax({
url: 'http://www.librarything.com/api_getdata.php?userid=F.L.O.W.&showstructure=1&showTags=1&booksort=title_REV',
type: 'get',
dataType: 'jsonp'
});
console.log(libraryData);
return libraryData;
}
});
编辑:2.4文档非常棒。Ember数据非常稳定。如果不是JSON API格式,你需要知道你得到的是什么类型的JSON,然后你需要序列化数据并将其转化为该格式。tumblr虽然看起来是一个友好的API,但实际上对Ember不太友好。Ember数据需要一种非常特定的JSON格式,而我如果答案不匹配,它就不会像许多简化教程那样“神奇”或“有效” 查找功能: 您的做法是正确的(定义自定义适配器)。您可以研究在适配器内重写buildURL 阅读并了解有关如何将传入的json转换为Ember喜欢的表单的更多详细信息 如果你放了一个jsbin,我可以看一看。更新,以及以上内容 工具(适配器和序列化程序) 要连接到一个不支持Ember数据的API(比如tumblr),您必须正确地构建请求,比如or (JSONAPIAdapter是RESTAdapter的一个子类,它调整JSON API的一些内容,例如规范所需的
Accept:application/vnd.API+JSON
头)
此外,如果检索到的数据不符合格式,则应选择最合适的序列化程序对后端返回的数据进行格式化和处理,例如,或。以下是这3个序列化程序的简短摘要:
JSONSerializer:
- 基本序列化程序(扩展抽象DS.serializer)
- 提供规范化钩子来处理接收到的数据
- 提供序列化钩子来处理发送的数据
- 需要通常的JSON格式
{
"id": 1,
"name": "Bob",
"friends": [array of friend ids],
"links": {
"home": "/bobshome"
}
}
在
:路线中的用法
但是,有多种方法可以实现这一点。您还可以将api密钥和主机url存储为适配器的属性,并仅使用它们来构建url(使用挂钩): 对于与Github API通信的简单Ember应用程序 社区驱动适配器作为示例:// ... model() { return this.store.findRecord('blog', 'mynameisbob'); } // ...
余烬前1.13.0 下面是一个关于如何编写自定义的简单示例。本质上,您需要做的是覆盖所需的商店查找挂钩(
,find
,findAll
),以及findQuery
) 因为它是一个外部API,我们需要担心CORS,所以我们还应该重写buildURL()
hook 自定义Tumblr适配器:ajax
如果响应没有正确格式化为余烬数据,我们可以在App.TumblrAdapter = DS.RESTAdapter.extend({ buildURL: function(type, id, record) { var tumblrBlogName = 'feministlibraryonwheels'; var tumblrApiKey = 'abcdefg'; var tumblrRequestUrl = 'http://api.tumblr.com/v2/blog/' + tumblrBlogName + '.tumblr.com' + '/posts?api_key=' + tumblrApiKey; return tumblrRequestUrl; }, ajax: function(url, method, hash) { hash = hash || {}; // hash may be undefined hash.crossDomain = true; // make it CORS hash.xhrFields = {withCredentials: true}; return this._super(url, method, hash); }, find: function(store, type, id, record) { // customization here or within buildURL return this.ajax(this.buildURL(), 'GET'); }, findAll: function(store, type, sinceToken) { // customization here or within buildURL return this.ajax(this.buildURL(), 'GET'); }, findQuery: function(store, type, query) { // customization here or within buildURL return this.ajax(this.buildURL(), 'GET'); }, findMany: function(store, type, ids, owner) { // customization here or within buildURL return this.ajax(this.buildURL(), 'GET'); } });
hook中快速修复它,只需一个简单的承诺:ajax
如果您希望正确地定义所有具有关系的模型,则需要实现一个定制来正确地传递数据 这是我自己在研究这些东西时遇到的一个问题。使用Ember 1.13.3 特别是关于Tumblr,我在adapters/post.js中有以下内容ajax: function(url, method, hash) { hash = hash || {}; // hash may be undefined hash.crossDomain = true; // make it CORS hash.xhrFields = {withCredentials: true}; return this._super(url, method, hash).then(function(json) { // Massage data to look like RESTAdapter expects. return { tumblrs: [json] }; }); },
import DS from "ember-data"; export default DS.RESTAdapter.extend({ host: 'https://api.tumblr.com', namespace: 'v2/blog/example.tumblr.com', apiKey: 'example', ajaxOptions() { var hash = this._super.apply(this, arguments); hash.data = hash.data || {}; hash.data.api_key = this.get('apiKey'); hash.dataType = 'jsonp'; return hash; } });
CLI的一部分是文件约定。在jsbin中,你能拥有完整的CLI环境吗?不,但是如果你用mockjax发布它,可能会更容易得到别人的帮助,在这一点上,你自己可以将它转换回CLI试图理解这一点。谢谢你的帮助。我知道你用了简单这个词3次,但我想这是主观的。LOL.@sHerifderek哈哈,我知道,我花了一些时间来掌握这些东西,如果你需要我澄清一些事情,请告诉我,但你确实需要彻底阅读余烬文档,特别是RESTAdapther和RESTSerializer的API页面,其中解释了所有这些方法 { "id": 1, "name": "Bob", "friends": [array of friend ids], "links": { "home": "/bobshome" } } { "user": { "id": 1, "name": "Bob", "friends": [array of friend ids], "links": { "home": "/bobshome" } } }export default DS.RESTAdapter.extend({ namespace: 'v2/blog/', // https://guides.emberjs.com/v2.0.0/models/customizing-adapters/#toc_endpoint-path-customization host: 'https://api.tumblr.com', // https://guides.emberjs.com/v2.0.0/models/customizing-adapters/#toc_host-customization headers: { // https://guides.emberjs.com/v2.0.0/models/customizing-adapters/#toc_headers-customization 'api_key': 'abcdefg' } // set any default ajax options you might need ajaxOptions(url, type, options = {}) { options.crossDomain = true; // make it CORS options.dataType = 'jsonp'; return this._super(url, type, options); } // find a blog findRecord: function(store, type, id, snapshot) { const URL = this.buildURL(type.modelName, id, snapshot, 'findRecord'); return this.ajax(URL, 'GET'); } });
// ... model() { return this.store.findRecord('blog', 'mynameisbob'); } // ...
export default DS.RESTAdapter.extend({ hostUrl: 'https://api.tumblr.com/v2/blog' apiKey: 'abcdefg', buildURL: function(modelName, id, snapshot, requestType, query) { // customize the url based on the parameters // lets assume the id is the blog name return `${this.get('hostUrl')}/${id}.tumblr.com/posts?api_key=${this.get('apiKey')}`; } // find a blog findRecord: function(store, type, id, snapshot) { const URL = this.buildURL(type.modelName, id, snapshot, 'findRecord'); return this.ajax(URL, 'GET'); } });
App.TumblrAdapter = DS.RESTAdapter.extend({ buildURL: function(type, id, record) { var tumblrBlogName = 'feministlibraryonwheels'; var tumblrApiKey = 'abcdefg'; var tumblrRequestUrl = 'http://api.tumblr.com/v2/blog/' + tumblrBlogName + '.tumblr.com' + '/posts?api_key=' + tumblrApiKey; return tumblrRequestUrl; }, ajax: function(url, method, hash) { hash = hash || {}; // hash may be undefined hash.crossDomain = true; // make it CORS hash.xhrFields = {withCredentials: true}; return this._super(url, method, hash); }, find: function(store, type, id, record) { // customization here or within buildURL return this.ajax(this.buildURL(), 'GET'); }, findAll: function(store, type, sinceToken) { // customization here or within buildURL return this.ajax(this.buildURL(), 'GET'); }, findQuery: function(store, type, query) { // customization here or within buildURL return this.ajax(this.buildURL(), 'GET'); }, findMany: function(store, type, ids, owner) { // customization here or within buildURL return this.ajax(this.buildURL(), 'GET'); } });
ajax: function(url, method, hash) { hash = hash || {}; // hash may be undefined hash.crossDomain = true; // make it CORS hash.xhrFields = {withCredentials: true}; return this._super(url, method, hash).then(function(json) { // Massage data to look like RESTAdapter expects. return { tumblrs: [json] }; }); },
import DS from "ember-data"; export default DS.RESTAdapter.extend({ host: 'https://api.tumblr.com', namespace: 'v2/blog/example.tumblr.com', apiKey: 'example', ajaxOptions() { var hash = this._super.apply(this, arguments); hash.data = hash.data || {}; hash.data.api_key = this.get('apiKey'); hash.dataType = 'jsonp'; return hash; } });