javascript-在API响应中使用包含关系时,使用isPending,isSettled,isFulfilled的Ember 2行为异常
作者:互联网
我需要彻底了解为什么财产会
isSettled
等待中
isFulfilled
如果我不包含API响应中的数据,则会有所不同.
我在这里问:https://discuss.emberjs.com/t/ember-2-show-a-single-loading-message-when-the-ids-where-included-in-the-original-response/12654,这使我想到了这种奇怪的行为:
如果我在我的API响应中包含数据(例如:model.posts),则这些属性会立即设置为true(并且.isPending为false),即使Chrome仍在加载实际数据(也是第一次!).
这是一个问题,因为我不知道posts []是否为空,也不知道该怎么做,因为类似的东西不起作用:
{{#each model.posts}}
My posts.
{{else}}
{{#if model.posts.isPending}}
<div>Loading...</div>
{{else}}
<div>Nothing to show.</div>
{{/if}}
{{/each}}
始终是“没什么可显示的”.直到加载Chrome.因为.isPending立即为假.
另外,如果我使用长度属性:
{{#if(eq model.posts.length 0)}}
因为起始posts []数组和空数组始终为length == 0.
如果我以不同的方式加载帖子,那么它可以异步运行,而不是侧面加载(但是有数百个HTTP请求,我不希望这样做).灰烬认出一个isPending …
为什么会有这种奇怪的行为?
UPDATE
我对/ category / 1的API响应:
{
"data": {
"id": "1",
"type": "categories",
"attributes": {
"name": "Book"
},
"relationships": {
"posts": {
"data": [{
"id": "11",
"type": "posts"
}, {
"id": "14",
"type": "posts"
}, {
"id": "16",
"type": "posts"
}]
}
}
},
"included": [{
"id": "11",
"type": "posts",
"attributes": {
"style": false,
"comments": true
}
}, {
"id": "14",
"type": "posts",
"attributes": {
"style": true,
"comments": false
}
}, {
"id": "16",
"type": "posts",
"attributes": {
"style": true,
"comments": false
}
}]
}
因为我在Rails控制器中使用了include.
其他策略?
>嵌入式:ids?
> JSON API链接?
怎么做?
我唯一的小宝贝问题:
我不需要很多HTTP请求.在第一个模型(类别)之后,仅一个用于类别(模型),一个(非阻塞,带有加载消息).
解决方法:
好的,我想首先告诉您有关加载数据的不同方法.在您的示例中,您有两个模型.我知道一个叫做发布,现在就让另一个叫做我的模型.
现在,您之间有了一对多的关系.在我的模型中大概是这样的:
posts: hasMany('post'),
现在显然您想显示给定my模型的所有帖子.为此,您可能具有类似/ my-model-posts /:myModel_id的路由.一个非常有趣的问题是如何链接到该路线.这是因为对于链接,您已经需要my-model实例,现在的问题是如何加载该实例…
我将稍后讨论,现在让我们假设您的用户直接在给定的URL上访问您的应用程序,因为这是您始终必须处理的用例.
因为命名约定为model_id,所以您不必自己编写路线.但是请记住,默认实现将等效于此显式路由定义:
model(params) {
return this.store.findRecord('my-model', params.myModel_id);
}
现在后端基本上有3种回应方式:
侧重一切
{
data: {
type: 'my-model',
id: 'foo',
attributes: {...},
relationships: {
posts: {
data: [{
type: 'post',
id: '1'
},{
type: 'post',
id: '2'
}]
}
}
},
included: [{
type: 'post',
id: '1',
attributes: {...}
}, {
type: 'post',
id: '2',
attributes: {...}
}]
}
加载ID
{
data: {
type: 'my-model',
id: 'foo',
attributes: {...},
relationships: {
posts: {
data: [{
type: 'post',
id: '1'
},{
type: 'post',
id: '2'
}]
}
}
}
}
使用相关链接
{
data: {
type: 'my-model',
id: 'foo',
attributes: {...},
relationships: {
posts: {
links: {
related: '/api/model/foo/posts'
}
}
}
}
}
现在,您需要了解findRecord返回的promise将等待服务器的第一个响应,然后再解决.您的路由器将在输入路由之前等待此响应.了解这一点非常重要:在此承诺解决之前,您的路线将不会输入.要指示此阶段的加载状态,可以使用a loading substate..
因此,对于第一个示例,如果您分担所有工作,这就足够了.请记住,返回响应时,没有更多数据要加载.同样,在加载此响应之前,您将处于加载子状态.
最后一个例子也不是很难.一种简单的方法是显示两个加载微调器.您需要这样做,因为您发出了两个请求并且处于两种加载状态:
>用户点击路线
>您发出findRecord请求
>显示加载子状态,直到findRecord请求完成
>返回响应,并将呈现模板
>您访问model.posts,这将触发相关链接的加载.在加载数据时,model.posts.isPending将为true.您可以使用简单的{{#if model.posts.isPending}}正在加载… {{/ if}}来指示加载状态
>返回响应,并且model.posts.isPending现在为false.现在已加载所有数据.
但是,您可以根据需要随意修改以将其减少到一个加载状态.您可以将帖子加载到您的afterModel
hook:中
afterModel(model) {
return model.get('posts');
}
这将强制在输入路线之前加载Promise帖子,使您始终处于loading substate.状态
另一件事是,如果您不关心my-model实例,则直接加载帖子:
model(params) {
return this.store.findRecord('my-model', params.myModel_id)
.then(m => m.get('posts'));
}
现在,模型将成为您的posts数组,并且您将一直处于loading子状态,直到发布posts为止.
最后但同样重要的是,我们来谈谈第二个示例:您仅加载ID.这可能是最棘手的问题.如果仅侧面加载id,则没有单个属性表示仍在加载某些内容.这是因为有许多HTTP请求,并且有很多承诺表明仍在加载某些内容.可能的唯一用例是当您实际上想尽快向用户显示数据时,因此我建议每篇文章使用加载优化程序:
{{#each model.posts as |post|}}
{{#if post.isLoading}}
loading...
{{else}}
...the data...
{{/if}}
{{else}}
no posts
{{/each}}
请注意,如果您没有任何帖子,则必须先提出一个HTTP请求,这才是您所知道的!
如果您想要一个加载微调器,则可以在my-model上创建一个计算属性:
hasLoadingPosts: Ember.computed('posts.@each.isLoading', {
get() {
return this.get('posts').any(post => post.get('isLoading'));
}
})
您也可以将其保留在loading子状态中,但这比较棘手:
afterModel(model) {
return model.get('posts')
.then(posts => Ember.RSVP.all(posts.toArray()));
}
您可以在模型挂钩中执行类似的操作:
model(params) {
return this.store.findRecord('my-model', params.myModel_id)
.then(m => m.get('posts'))
.then(posts => Ember.RSVP.all(posts.toArray()));
}
还请注意,这最后两个承诺处理JS代码段在所有情况下均有效.如果数据已经加载,它们不会受到损害,但是要等待相关的链接以及侧面加载的ID.
现在,需要注意的一个非常重要的事情是通常不直接链接到这样的页面.可能您在某处有一个我的模型列表或其他内容,然后有一个链接以显示这些帖子.在这里,您将不会碰到模型钩!您也不需要此第一个请求:my-model的数据已在商店中!现在的问题是,首先加载它时返回了什么.您是否仅加载了ID或使用了相关链接来加载所有内容?结果与以上情况类似!
如果您修改了模型挂钩,则可能还应该将链接更改为从{{#link-到’my-model-posts’模型}}到{{#link-到’my-model-posts’模型.帖子}}.这很不错,因为如果您使用了相关链接,则路由将再次等待此承诺解决.
通常,我的建议是不要仅加载ID.这可能仅在您不将关系数据库用于后端的情况下才有用.
我建议使用相关链接,并在极少数情况下侧重加载所有内容.例如,如果您直接加载my-model,则将全部加载,而该列表仅返回相关链接.
现在只需要编程,因为只有相关的链接,通常情况下一切正常.如果有时需要较少的负载指示器,则可以.
另外,如果您仅显示此帖子数组,我将更改路线的语义并将其直接返回到模型挂钩中的数组中.当然,然后如上所述更改链接到.
但是,如果您想显示my-model的某些数据(例如标题),则可能希望尽快显示它们.在显示标题但还没有帖子时,这里需要isPending.
但是,如上所述,当您仅加载ID时,这两种解决方案都会中断.
标签:javascript,performance,rest,ember-js,ember-data 来源: https://codeday.me/bug/20191010/1884796.html