使用APP_INITIALIZER添加动态加载消息

问题描述 投票:0回答:1

我有一个应用程序在初始化之前执行一些后端调用。我有一个加载屏幕,它告诉用户当前正在加载某些内容。问题是我还想显示当前正在加载的内容。如果其中一个后端调用失败,它应该明确显示出了什么问题。为了说明问题,我编写了一个小示例应用程序。

app.module.ts

import { APP_INITIALIZER, NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatButtonModule } from '@angular/material/button';
import { MatMenuModule } from '@angular/material/menu';
import { MatTreeModule } from '@angular/material/tree';
import { MatIconModule } from '@angular/material/icon';
import { MatInputModule } from '@angular/material/input';
import { TreeNodeComponent } from './tree-node/tree-node.component';
import { ListElementComponent } from './list-element/list-element.component';
import { HttpClient } from '@angular/common/http';
import { forkJoin, switchMap, tap } from 'rxjs';
import { UserService } from './user.service';
import { ProudctService } from './proudct.service';

@NgModule({
  declarations: [
    AppComponent,
    TreeNodeComponent,
    ListElementComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    BrowserAnimationsModule,
    MatButtonModule,
    MatMenuModule,
    MatTreeModule,
    MatIconModule,
    MatInputModule
  ],
  providers: [{
    provide: APP_INITIALIZER,
    multi: true,
    deps: [UserService, ProudctService],
    useFactory: getUserConfig
  }],
  bootstrap: [AppComponent]
})
export class AppModule { }




export function getUserConfig(userService: UserService, productService: ProudctService) {
  return function () {
    switchMap(() => {
        const user$ = userService.getUsers();

        const product$ = productService.getAllProducts();

        return forkJoin([user$, product$]);
    })
  }
}

index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>FocusManagerPlayground</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500&display=swap" rel="stylesheet">
  <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
</head>
<body class="mat-typography">
  <app-root>
    <div class="splash">Loading User... </div><div *ngIf="loading">Succesfull</div><div *ngIf="!loading">failed</div>
    <div class="splash">Loading Product...</div>
  </app-root>
  <app-loading></app-loading>
</body>
</html>

这是它应该是什么样子的屏幕截图: 如果第一次后端调用成功,加载消息的右侧应该有一个成功图标,如果失败,应该有一个失败图标。与加载产品相同。 enter image description here

html angular typescript
1个回答
-3
投票

不确定您的示例是您所做的还是只是为了说明,但是您在组件中没有加载消息是否有原因?我会将您的消息放入一个组件中,然后将调用分离到在初始化时启动的服务中。该组件可以引用该服务,然后您可以使用类似标志之类的东西来更新模板。

app.module.ts

export const userFactory = (provider: UserService): (() => Promise<void>) => () => provider.load();

@NgModule({
    providers: [
        UserService,
        { provide: APP_INITIALIZER, useFactory: userFactory, deps: [UserService], multi: true },

示例服务——仅以 UserService 为例

@Injectable()
export class UserService {
 usersLoading: boolean
 usersLoadError: boolean
 user: any;
  load(): void {
    this.usersLoading = true;
    this.getData();
  }

  getData() {
    setTimeout(() => {
      this.user = { id: 1, name: 'hi' };
      this.usersLoading = false;
      this.usersLoadError = false;
    }, 5000);
  }
}

模板——我不太喜欢标志,但只是用这里来表达一个观点,你也可以检查用户属性是否真实。


@Component({
  selector: 'hello',
  template: `<h1>Hello {{name}}!</h1>
    {{userService.usersLoading ? 'Loading' : 'loaded' }}`,
  styles: [`h1 { font-family: Lato; }`],
})
export class HelloComponent {
  @Input() name: string;

  constructor(public userService: UserService) {}
}


请在此处找到一个工作示例:https://stackblitz.com/edit/angular-tj57g2?file=src/app/user.service.ts

© www.soinside.com 2019 - 2024. All rights reserved.