在我的 Angular 应用程序中,我使用 CSS 开发了一个具有两列的布局组件。在此布局组件内,我使用
ng-content
为旁白和主要内容定义了占位符。
旁白和主要部分的数据是从服务器获取的。在加载阶段,会设置一个
loading
标志来指示正在获取数据。成功检索数据后,会从可观察对象中返回一个 isSuccess
标志以及响应。
为了模拟这种行为,我使用 RxJS 中的
data$
运算符创建了一个模拟 of
可观察对象。此可观察量包括模仿异步数据检索过程的延迟。
布局未正确渲染旁白和主要内容。出现此问题的原因是
ng-content
指令直接需要属性 aside
和 main
,但它们深深嵌套在 ng-container
内部。
问题是,可以修改此设置以正确呈现内容吗?
这是修改后的代码:
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { delay, of, startWith } from 'rxjs';
import 'zone.js';
@Component({
selector: 'layout',
standalone: true,
template: `
<div class="container">
<aside>
<ng-content select="[aside]"></ng-content>
</aside>
<main>
<ng-content select="[main]"></ng-content>
</main>
</div>
`,
styles: [`.container {display:grid; grid-template-columns: 1fr 2fr} `],
})
export class LayoutComponent {}
@Component({
selector: 'app-root',
standalone: true,
imports: [LayoutComponent, CommonModule],
template: `
<layout>
<ng-container *ngIf="data$ | async as result">
<div *ngIf="result.loading">loading...</div>
<ng-container *ngIf="result.isSuccess">
<div aside>aside content: {{ result.response.aside | json }}</div>
<div main>main content: {{ result.response.main | json }}</div>
</ng-container>
</ng-container>
</layout>
`,
})
export class App {
data$ = of<any>({
response: { aside: [1, 2, 3, 4], main: [10, 12, 13, 14] },
isSuccess: true,
}).pipe(delay(1 * 1000), startWith({ loading: true }));
}
bootstrapApplication(App);
这是代码的链接:StackBlitz
ng-content
标签必须出现在顶层,以便内容投影可见。
所以我重构了 HTML,以便我们获取数据并根据是否满足所有条件有条件地显示内容,然后使用
if else (ng-template)
我们可以显示加载部分!
请随意修改代码以满足您的要求!
完整代码:
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { bootstrapApplication } from '@angular/platform-browser';
import { delay, of, startWith } from 'rxjs';
import { endWith } from 'rxjs/operators';
import 'zone.js';
console.clear();
@Component({
selector: 'layout',
standalone: true,
template: `
<div class="container">
<aside>
<ng-content select="[aside]"></ng-content>
</aside>
<main>
<ng-content select="[main]"></ng-content>
</main>
</div>
`,
styles: [`.container {display:grid; grid-template-columns: 1fr 2fr} `],
})
export class LayoutComponent {}
@Component({
selector: 'app-root',
standalone: true,
imports: [LayoutComponent, CommonModule],
template: `
<ng-container *ngIf="data$ | async as result">
<layout *ngIf="result.isSuccess;else loading">
<div aside>aside content: {{ result.response.aside | json }}</div>
<div main>main content: {{ result.response.main | json }}</div>
</layout>
</ng-container>
<ng-template #loading>
<div>loading...</div>
</ng-template>
`,
})
export class App {
name = 'Angular';
data$ = of<any>({
response: { aside: [1, 2, 3, 4], main: [10, 12, 13, 14] },
isSuccess: true,
}).pipe(delay(1 * 1000), startWith({ loading: true }));
}
bootstrapApplication(App);