如何在Angular中构建延迟加载侧边栏?

时间:2019-11-04 17:42:04

标签: javascript angular typescript lazy-loading angular-ng-if

我已经在Angular App中构建了一个组件来处理客户信息。这是我的ClientDetailsComponent,在此组件中还有其他子组件,当用户输入主ClientDetailsComponent时,每个子组件都会获取自己的数据;当然,这会导致主要组件加载很多用户目前可能甚至不需要的东西,因此我试图寻找一种方法来延迟加载此部分。

现在,我的组件有一个侧边栏,可作为导航菜单,仅在单击时显示特定部分,现在,我已经建立了一个非常原始的导航菜单,依靠类来隐藏/显示每个部分。

ClientDetailsCompnent

<div class="wrapper">
    <div class="sidebar-nav">
        <nav>
            <ul class="sections-list" btnRadioGroup [formControl]="navControl">
                <li btnRadio="0" tabindex="0" role="button">Basic Information</li>
                <li btnRadio="1" tabindex="0" role="button" *ngIf="!isNew">PPC Accounts</li>
                <li btnRadio="2" tabindex="0" role="button" *ngIf="!isNew">Campaign Groups</li>
                <li btnRadio="4" tabindex="0" role="button" *ngIf="!isNew">Optimizations</li>
                <li btnRadio="5" tabindex="0" role="button" *ngIf="!isNew">Branding</li>
                <li btnRadio="3" tabindex="0" role="button" *ngIf="!isNew">Sharing</li>
            </ul>
        </nav>
    </div>
    <div class="content">
        <div class="wsm-container">

            <!-- Basic Information -->
            <section id="basic-info" class="wsm-card mx-auto d-none" [ngClass]="navControl.value === '0' ? 'd-flex' : 'd-none'">
            </section>

            <!-- PPC Accounts -->
            <section *ngIf="!isNew" id="ppc-accounts" class="wsm-card mt-4 d-none" [ngClass]="navControl.value === '1' ? 'd-flex' : 'd-none'">
            </section>

            <!-- Campaign Groups -->
            <section *ngIf="!isNew && navControl.value === '2'" class="wsm-card mt-4 d-none" [ngClass]="navControl.value === '2' ? 'd-flex' : 'd-none'">
                <app-campaign-groups [clientID]="param"></app-campaign-groups>
            </section>

            <!-- Optimizer History -->
            <section *ngIf="!isNew && navControl.value === '4'" id="optHistory" class="wsm-card mt-4 d-none" [ngClass]="navControl.value === '4' ? 'd-flex' : 'd-none'">
                <app-optimization-history></app-optimization-history>
            </section>

            <!-- Branding -->
            <section id="brnading" class="wsm-card mx-auto d-none" [ngClass]="navControl.value === '5' ? 'd-flex' : 'd-none'">
            </section>
        </div>
    </div>
</div>

关于导航,一切工作都和我预期的差不多,一次只显示一个部分,具体取决于我在侧边栏上单击的项目。但是,这样做并不能阻止我在访问组件时立即发出所有请求。

因此,我在尝试各种选项时发现的一种解决方法是,在本节的navControl.value === ''指令上使用*ngIf条件,因此,我不仅使用[ngClass]指令更改了类,也阻止了将该部分添加到DOM,实际上,我看到对每个子组件的请求仅在单击所需的选项卡后才发出。

现在的问题是,每当我在各节之间移动时,都会添加/删除该组件,因此我单击其他选项卡时,请求是在eveytime上完成的。

是否有一种方法可以在我访问子组件后使其保持加载状态,从而无需重新渲染它并再次获取数据?

1 个答案:

答案 0 :(得分:2)

使用ReplaySubject创建服务

@Injectable({
  providedIn: "root"
})
export class DataService {
  private _replay: ReplaySubject<any>;
  get replay() {
    if (!this._replay) {
      this._replay = new ReplaySubject();
      this.fakeFetch().then(data => this.replay.next(data));
    }
    return this._replay;
  }

  async fakeFetch() {
    console.log("fakeFetch");
    await new Promise(c => setTimeout(() => c(), 10));
    return { name: "world" };
  }
}

然后在您的组件中订阅重播主题:

export class HelloComponent {
  name: string;
  constructor(private api: DataService) {
    console.log('render HelloComponent')
    this.api.replay.subscribe(data => {
      this.name = data.name;
    });
  }
}

stackblitz