html - زمانی که ngIf برابر false است، ng-content در Angular4 ساخته میشود
من با ترنسلوشن جدید ng-content مشکلی دارم.
فرض کنید من یک کامپوننت my-component دارم که در تابع ngOnInit() خود یک عملیات سنگین در هنگام بارگذاری انجام میدهد (فعلاً فقط یک console.log()).
من یک Wrapper دارم که محتوا را از طریق ترنس کلوزیون (my-wrapper.component.html) نمایش میدهد.
<ng-content></ng-content>
اگر محیط را اینطور راهاندازی کنم، عبارت log نمایش داده نمیشود:
<my-wrapper *ngIf="false">
<my-component></my-component>
</my-wrapper>
من فرض میکنم که کامپوننت my-wrapper ساخته نمیشود، بنابراین محتوا نادیده گرفته میشود.
اما اگر سعی کنم منطق را به کامپوننت my-wrapper به این شکل منتقل کنم (my-wrapper.component.html):
<ng-container *ngIf="false">
<ng-content></ng-content>
</ng-container>
من همیشه خروجی console.log() را میبینم. حدس میزنم، my-component ساخته میشود و سپس ذخیره میشود تا زمانی که *ngIf داخل my-wrapper به true تبدیل شود.
قصد این بود که یک کامپوننت عمومی «مورد فهرست + جزئیات» بسازیم. فرض کنید من یک فهرست از N عنصر مرور کلی (my-wrapper) دارم که در یک حلقه *ngFor رندر میشوند. هر کدام از این عناصر یک کامپوننت جزئیات مخصوص خودشان (my-component) دارند که قرار است دادههای خود را بارگذاری کنند، به محض اینکه تصمیم میگیرم اطلاعات بیشتری از یک مورد خاص نشان دهم.
overview.html:
<ng-container *ngFor="let item of items">
<my-wrapper>
<my-component id="item.id"></my-component>
</my-wrapper>
</ng-container>
my-wrapper.component.html:
<div (click)="toggleDetail()">Click for more</div>
<div *ngIf="showDetail">
<ng-content></ng-content>
</div>
آیا راهی وجود دارد که به Angular بگوییم تا محتوای درجشده را نادیده بگیرد تا زمانی که لازم باشد به صفحه اضافه شود؟ به طور مشابه با نحوه آن در AngularJS.
پاسخ شماره ۱
بر اساس نظر @nsinreal، من جوابی پیدا کردم. آن را کمی پیچیده مییابم، بنابراین سعی میکنم آن را اینجا منتشر کنم:
پاسخ این است که با ng-template و *ngTemplateOutlet کار کنید.
در کامپوننت my-wrapper، قالب را به این صورت تنظیم کنید (my-wrapper.component.html):
<div (click)="toggleDetail()">Click for more</div>
<div *ngIf="showDetail" [hidden]="!isInitialized">
<ng-container *ngTemplateOutlet="detailRef"></ng-container>
</div>
توجه داشته باشید که [hidden] آنجا واقعاً ضروری نیست، این عنصر قالب «خام» فرزند را تا زمانی که تصمیم بگیرد بارگذاری کامل شده است مخفی میکند. فقط مطمئن شوید که آن را داخل *ngIf قرار ندهید، در غیر این صورت *ngTemplateOutlet هرگز فعال نخواهد شد و هیچ اتفاقی نمیافتد.
برای تنظیم detailRef، این را در کد کامپوننت قرار دهید (my-wrapper.component.ts):
import { ContentChild, TemplateRef } from '@angular/core';
@Component({ ... })
export class MyWrapperComponent {
@ContentChild(TemplateRef) detailRef;
...
}
حالا میتوانید از بستهبندیکننده به این شکل استفاده کنید:
<my-wrapper>
<ng-template>
<my-component></my-component>
</ng-template>
</my-wrapper>
من مطمئن نیستم که چرا نیاز به چنین «راهحلهای پیچیده» دارد، وقتی که انجام این کار در AngularJS بسیار آسان بود.
