在Angular2中加载数据之前显示页面

时间:2017-01-19 18:01:05

标签: angular angular2-template resolver

如果Angular2模板依赖于数据才能显示,并且尚未加载数据,则会导致整个应用程序中断,需要用户重新加载其页面。

Angular2解析器是解决此问题的方法。解析器会阻止页面加载,直到其promise或observable结算为止。但问题是,在解析器结算之前,页面根本不会被渲染。

如果您想要显示页面(例如,在微调器后面),只有在数据可用后才显示,会发生什么?有没有办法在仍然使用解析器的Angular2中执行此操作,或者是在组件中实现自己的服务调用的唯一方法,模板中的逻辑可以防止数据在不可用时被使用?例如,模板中的每个{{ foo.bar }}都必须更改为{{ foo && foo.bar }}

是否有一种Angular2友好的方法来做到这一点?

2 个答案:

答案 0 :(得分:1)

假设您在组件中解析数据,不需要像

那样进行双重检查
{{foo && foo.bar}}

只需使用问号运算符,如果要解析嵌套属性并且每个属性都可能未定义,这样很方便:

{{foo?.bar?.another?.property}}

但是,您可能很快发现自己在HTML中使用了大量的?。这就是为什么使用?对于尚未解决的数据可能有点难看。

另一个解决方案是将所有内容都包含在ngIf这样的

 <div *ngIf="loading">Page is loading</div>
 <div *ngIf="!loading"> {{foo.bar}} </div>

另一方面,如果您有多个组件,则可能会在页面上传播许多微调器图标加载...邮件。或者您只需将ngIf放在特定内容区域的顶级组件中即可。我要说,这取决于您的使用案例和您的个人用户体验偏好。

答案 1 :(得分:1)

  

解析器会阻止页面加载,直到其promise或observable结算为止。但问题是,在解析器结算之前,页面根本不会被渲染。

更具体地说,解决方案会阻止激活路线。但是页面/ UI的某些部分仍然被加载(并且可能被渲染),因为路由器无法控制100%的视图。

至少,您仍然拥有包裹AppComponent的根组件,即<router-outlet></router-outlet>

您可以将微调器的标记放在AppComponent的模板中,并使用服务启动/停止它。

然后,在Resolve中注入此服务以协调微调器和异步操作。更具体地说,在resolve()方法中你可以:

  • 启动微调器。
  • 将{stop spinner'回调附加到onCompleteonError事件(假设您正在使用observable)。
  • 返回异步操作的observable(例如HTTP调用)。

您的微调器的显示方式取决于您使用的CSS框架。它可能是一个覆盖整个屏幕(有点像模态)或屏幕一角的小通知。

进一步改进:为什么不监视Http服务(或使用自定义集中服务来包装所有HTTP调用),以便只要有正在进行的HTTP调用就可以启动和停止微调器(前提是这是所需的行为...)。这样,您就不必在每个分析中处理微调器的手动启动和停止。