【问题标题】:Display pages before their data is loaded in Angular2在 Angular2 中加载数据之前显示页面
【发布时间】:2026-01-29 15:00:01
【问题描述】:

如果 Angular2 模板依赖于数据才能显示,而该数据尚未加载,则会导致整个应用程序崩溃,需要用户重新加载他的页面。

Angular2 解析器是解决这个问题的方法。解析器会阻止页面加载,直到它们的 promise 或 observable 解析。但问题是,在解析器解决之前,页面根本不会被呈现。

如果您希望页面显示(例如,在微调器后面),并且只在数据可用时显示数据,会发生什么情况?在 Angular2 中是否有一种方法可以做到这一点,它仍然使用解析器,或者是在组件中实现自己的服务调用的唯一方法,在模板中使用逻辑来防止数据在不可用时被使用?例如,模板中的每个 {{ foo.bar }} 都必须更改为 {{ foo && foo.bar }}

是否有对 Angular2 友好的方法来执行此操作?

【问题讨论】:

    标签: angular angular2-template resolver


    【解决方案1】:

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

    那样仔细检查
    {{foo && foo.bar}}
    

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

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

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

    另一种解决方案是像这样将所有内容包装在ngIf

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

    另一方面,如果您有多个组件,则可能会有许多微调器图标正在加载...消息遍布整个页面。或者,您只需将 ngIf 放在特定内容区域的*组件中。我想说,这取决于您的用例和您的个人用户体验偏好。

    【讨论】:

    • 谢谢。我的问题主要是关于如何在保持解析器模式的同时做这些事情(多个微调器,页面显示)。否则,您需要在组件中添加自定义逻辑以确定是否已加载数据。我在问如何在不必这样做的情况下显示页面。
    • 我认为这是不可能的。引用“例如,在联系人应用程序中,我们可以单击联系人查看联系人的详细信息,联系人数据应该在我们路由到的组件被实例化之前加载”(blog.thoughtram.io/angular/2016/10/10/…
    • 如果组件在 Resolver 完成之前没有被实例化,就没有机会渲染组件的视图。无论如何,我想这是 Resolver 的目标之一。
    【解决方案2】:

    解析器会阻止页面加载,直到它们的 promise 或 observable 解析。但问题是,在解析器解决之前,页面根本不会被呈现。

    更具体地说,解析会阻止路由被激活。但是由于路由器无法控制 100% 的视图,页面/UI 的某些部分仍会加载(并且可能会呈现)。

    至少,您仍然拥有包装&lt;router-outlet&gt;&lt;/router-outlet&gt; 的根组件,即AppComponent

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

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

    • 启动微调器。
    • 将“停止微调器”回调附加到 onCompleteonError 事件(假设您使用的是 observables)。
    • 为异步操作(例如 HTTP 调用)返回 observable。

    微调器的显示方式取决于您使用的 CSS 框架。它可以是使全屏变暗的叠加层(有点像模式)或屏幕一角的小通知。

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

    【讨论】: