英文原版:https://guides.emberjs.com/v2.14.0/models/pushing-records-into-the-store/
认知store的其中一种方法是将它作为已读取的记录的缓存。如果route或controller需要获得记录,那么store可以立即返回已被缓存的记录;否则store会向适配器索取记录,这通常意味着将会向服务器发起一个请求。
相对于等待从远端获取记录,你也可以将一条记录推送到store的缓存中。
如果用户在某个步骤后立即要使用这条记录,那么这会非常有用。当用户点击一个超链接,与其等待完成一个请求,Ember可以立即渲染一个新模版。这会在瞬间完成。
另一个可以利用此机制的场景是,你的应用通过流链接到服务器,并且如果一条记录被创建或被编辑,你想立即更新UI。
通过调用store的push()可以将一条记录推入store。
例子,假设我们想在应用一启动的时候从store预加载一些数据。
我们可以利用application路由实现这个功能。application路由在路由层级的顶层,并且它的model钩子函数会在应用启动的时候就被调用。
app/models/album.js
import DS from 'ember-data';
export default DS.Model.extend({
title: DS.attr(),
artist: DS.attr(),
songCount: DS.attr()
});
app/routes/application.js
import Ember from 'ember';
export default Ember.Route.extend({
model() {
this.get('store').push({
data: [{
id: 1,
type: 'album',
attributes: {
title: 'Fewer Moving Parts',
artist: 'David Bazan',
songCount: 10
},
relationships: {}
}, {
id: 2,
type: 'album',
attributes: {
title: 'Calgary b/w I Can\'t Make You Love Me/Nick Of Time',
artist: 'Bon Iver',
songCount: 2
},
relationships: {}
}]
});
}
});
store的push()是一个低等级的API,它遵循的JSON API文档与JSONAPISerializer 遵循的JSON API文档有一些区别。JSON API数据格式中的type名必须与定义model的文件名一致;属性名和关系名称必须与model类中的定义一致。
如果你希望数据在被推入store之前需要被默认的模型序列化器规范化,你可以使用store.pushPayload() 方法:
app/serializers/album.js
import DS from 'ember-data';
export default DS.RestSerializer.extend({
normalize(typeHash, hash) {
hash['songCount'] = hash['song_count']
delete hash['song_count']
return this._super(typeHash, hash);
}
})
app/routes/application.js
import Ember from 'ember';
export default Ember.Route.extend({
model() {
this.get('store').pushPayload({
albums: [
{
id: 1,
title: 'Fever Moving Parts',
artist: 'David Bazan',
song_count: 10
},
{
id: 2,
title: 'Calgary b/w I Can\'t Make You Love Me/Nick Of Time',
artist: 'Bon Iver',
song_count: 2
}
]
});
}
});
在你使用复杂的终端时push()方法也很重要。你可能会发现你的应用会执行一些业务逻辑,然后创建一些记录。这可能不会清晰的映射到Ember Data现有的save()方法。相反的,你需要自定义AJAX请求并且将响应数据推入store,以至于可以让应用的其他部分访问它。
app/routes/confirm-payment.js
import Ember from 'ember';
export default Ember.Route.extend({
actions: {
confirm: function(data) {
$.ajax({
data: data,
method: 'POST',
url: 'process-payment'
}).then((digitalInventory) => {
this.get('store').pushPayload(digitalInventory);
this.transitionTo('thank-you');
});
}
}
});
在模型中定义但在规范化的JSON API文档对象中省略的属性将不会更新。 包含在规范化的JSON API文档对象中但未在模型中定义的属性将被忽略。
本节完