如何在 Angular 中构建延迟加载侧边栏?
How to build lazy-loading sidebar in Angular?
我在我的 Angular 应用程序中构建了一个组件来处理客户信息;这是我的 ClientDetailsComponent
,在这个组件内部还有其他子组件,当用户进入主 ClientDetailsComponent
时,每个子组件都会获取自己的数据;这当然会导致主要组件加载很多用户目前可能不需要的东西,所以我试图寻找一种方法来延迟加载这些部分。
现在我的组件有一个侧边栏用作导航菜单,仅在单击时显示特定部分,现在我已经构建了一个非常原始的导航菜单,依赖于 类 到 hide/show每个部分。
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>
关于导航,一切都和我预期的一样,一次只显示一个部分,具体取决于我在边栏上单击的项目;但是,仅仅这样做并不能阻止在我访问该组件时立即发出所有请求。
所以我在尝试各种选项时发现的一种解决方法是在该部分的 *ngIf
指令上使用 navControl.value === ''
条件,而不是仅将 类 更改为 [ngClass]
指令,我还阻止将部分添加到 DOM,事实上我看到每个子组件的请求只有在我单击所需的选项卡后才会发出。
现在的问题是每次我单击不同的选项卡时都会发出请求,因为每次我在各个部分之间移动时组件都是 added/removed。
有没有办法让子组件在我访问后保持加载状态,这样它就不需要重新渲染它并再次获取数据?
使用 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;
});
}
}
我在我的 Angular 应用程序中构建了一个组件来处理客户信息;这是我的 ClientDetailsComponent
,在这个组件内部还有其他子组件,当用户进入主 ClientDetailsComponent
时,每个子组件都会获取自己的数据;这当然会导致主要组件加载很多用户目前可能不需要的东西,所以我试图寻找一种方法来延迟加载这些部分。
现在我的组件有一个侧边栏用作导航菜单,仅在单击时显示特定部分,现在我已经构建了一个非常原始的导航菜单,依赖于 类 到 hide/show每个部分。
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>
关于导航,一切都和我预期的一样,一次只显示一个部分,具体取决于我在边栏上单击的项目;但是,仅仅这样做并不能阻止在我访问该组件时立即发出所有请求。
所以我在尝试各种选项时发现的一种解决方法是在该部分的 *ngIf
指令上使用 navControl.value === ''
条件,而不是仅将 类 更改为 [ngClass]
指令,我还阻止将部分添加到 DOM,事实上我看到每个子组件的请求只有在我单击所需的选项卡后才会发出。
现在的问题是每次我单击不同的选项卡时都会发出请求,因为每次我在各个部分之间移动时组件都是 added/removed。
有没有办法让子组件在我访问后保持加载状态,这样它就不需要重新渲染它并再次获取数据?
使用 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;
});
}
}