在目前的项目工作中,我们(特指Pharbers项目)还没有完全使用 Ember Models的一些原生的 特性,都是经过了一层封装,但是在 BM 项目中已经开始使用完全符合 JSONAPI 以及 Ember Data 的规范。所以这里完全是按照官方的符合JSONAPI 的规范。
有两种方法:
// route.js
model() {
return this.get('store').findAll('company');
}
以及:
// route.js
model() {
return this.get('store').peekAll('company');
}
其中,findAll()
方法返回的是DS.PromiseArray
,在经过 resolve 之后返回的才为 DS.RecordArray
。而peekAll()
返回的直接为 DS.RecordArray
。从这里可以看出来 findAll()
方法是发送了 promise 请求,而 peekAll()
则是直接读取了 缓存 中存在的数据。
// route.js
model() {
return this.get('store').findAll('company');
},
actions: {
requestAgain() {
let that = this;
this.get('store').findAll('company', { reload: true }).then(data => {
that.controllerFor('model-demo.fetch').set('companiesAgain', data);
});
}
}
在触发了 requestAgain
action 之后,在网速较慢的情况下就会看到页面在数据返回之后才进行了展示。如果去掉 {reload: true}
,再次触发requestAgain
action 之后会发现 页面会立即展示 缓存 中的数据。
此属性和 adapter
中的 shouldReloadAll()
方法起到的作用类似。
上述做法只是为了更好的展示本option的作用
作用与 adapter
中的 shouldBackgroundReload()
方法类似,可以查看 这篇文档。
使用上面的例子进行演示就是:
// route.js
model() {
return this.get('store').findAll('company', { backgroundReload: false });
},
加了这个backgroundReload: false
属性之后,在跳转其他页面再回来之后就不会再次发送请求。默认为 true
。
在本例中,如果 company
的model 实例有个一对多的 phones
关系,那么在请求的时候可以:
// route.js
model() {
return this.get('store').findAll('company', { include: 'phones' });
},
其中 company
的model.js
文件为:
import DS from 'ember-data';
export default DS.Model.extend({
name: DS.attr('string'),
address: DS.attr('string'),
foundingTime: DS.attr('date'),
employee: DS.attr('number'),
phones: DS.hasMany('phone'),
isLocation: DS.attr('boolean'),
logo: DS.attr('string')
});
这样其下相关的 phone
就会在请求 company
的时候也请求到。
将已经存在于 缓存 中的数据读取出来,不会发送请求。所以如果本地缓存没有数据的话,返回长度为零的数组。
和上述api 类似的是:
同样的 findRecord()
会发送请求,也接受一些参数,而peekRecord()
不会发送请求。
基本使用:
// route.js
model() {
return this.get('store').findRecord('phone', 1);
},
将会返回id
为1
的 phone
的数据;
使用:
// route.js
model() {
return this.get('store').findRecord('phone', 1, { preload: { company: 1 }});
},
与findAll()
的相同。
同 peekAll()
,增加一个参数,为获取 record
的id。
可以对查询的条件进行筛选并返回相应的筛选后的数据:
// route.js
queryFilter() {
this.get('store').query('company', {
filter: {
isLocation: true
}
}).then(companies => {
this.controllerFor('model-demo.fetch').set('queryFilter', companies);
});
}
此action 被触发后会将 company
中isLocation
属性为true
的record 返回来展示在页面中。
需要注意的是,此方法同样返回一个 promise
。
Ember Data 默认使用的 JSONAPIAdapter 并不支持此方法,若想要查询单一的record,可以:
// route.js
querySingleRecord() {
this.get('store').query('company', {
filter: {
isLocation: true
}
}).then(companies => {
this.controllerFor('model-demo.fetch').set('querySingleRecord', companies.get('firstObject'));
});
这个就是将查询到的数组的第一项展示出来。
Written By FrankWang.