Within my Angular application, I have designed a layout component featuring two columns using CSS. Within this setup, placeholders for the aside and main content are defined utilizing ng-content
.
The data for both the aside and main sections is fetched from the server. A loading
flag is set during the loading phase to signify that data retrieval is in progress. Once successful data retrieval occurs, an isSuccess
flag is returned alongside the response from the observable.
To replicate this process, I've crafted a mock data$
observable with the help of the RxJS of
operator. This observable includes a delay to mirror the asynchronous nature of data retrieval.
An issue has surfaced where the layout fails to properly render the aside and main content. This problem arises due to the fact that the ng-content
directive anticipates the attributes aside
and main
directly, but they exist deeply nested inside ng-container
.
The question at hand is whether it's feasible to modify this setup to correctly showcase the content?
Below is the revised code snippet:
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);
Access the code at this link: StackBlitz