假设我有一个组件:
@Component({
selector: 'MyContainer',
template: `
<div class="container">
<!-- some html skipped -->
<ng-content></ng-content>
<span *ngIf="????">Display this if ng-content is empty!</span>
<!-- some html skipped -->
</div>`
})
export class MyContainer {
}
现在,如果此组件的<ng-content>
为空,我想显示一些默认内容。如果不直接访问DOM,有没有简单的方法呢?
答案 0 :(得分:68)
在ng-content
之类的HTML元素中包装div
以获取对其的本地引用,然后将ngIf
表达式绑定到ref.children.length == 0
:
template: `<div #ref><ng-content></ng-content></div>
<span *ngIf="ref.nativeElement.childNodes.length == 0">
Display this if ng-content is empty!
</span>`
答案 1 :(得分:11)
@pixelbits答案中有些遗漏。我们不仅需要检查children
属性,因为父模板中的任何换行符或空格都会导致children
元素带有空白文本\换行符。
最好检查一下.innerHTML
和.trim()
。
工作示例:
<span #ref><ng-content></ng-content></span>
<span *ngIf="!ref.innerHTML.trim()">
Content if empty
</span>
答案 2 :(得分:8)
注入内容时添加引用变量:
<div #content>Some Content</div>
并在您的组件类中使用@ContentChild()
获取对注入内容的引用@ContentChild('content') content: ElementRef;
因此,在组件模板中,您可以检查内容变量是否具有值
<div>
<ng-content></ng-content>
<span *ngIf="!content">
Display this if ng-content is empty!
</span>
</div>
答案 3 :(得分:8)
这是CSS解决方案。 如果ng-content中未设置默认组件,则可以提供默认组件。由于他们是我的兄弟姐妹,因此可以这样解决。
自IE 9起兼容,部分自IE7 / 8起兼容:https://caniuse.com/#feat=css-sel3
HTML
<div class="my-custom-component-content-wrapper">
<ng-content select="my-custom-component"></ng-content>
</div>
<my-custom-component>
This shows something default.
</my-custom-component>
CSS
.my-custom-component-content-wrapper:not(:empty) + my-custom-component {
display: none;
}
答案 4 :(得分:5)
注入elementRef: ElementRef
并检查elementRef.nativeElement
是否有孩子。这可能仅适用于encapsulation: ViewEncapsulation.Native
。
换行<ng-content>
标记并检查它是否有子项。这不适用于encapsulation: ViewEncapsulation.Native
。
<div #contentWrapper>
<ng-content></ng-content>
</div>
并检查它是否有孩子
@ViewChild('contentWrapper') contentWrapper;
ngAfterViewInit() {
contentWrapper.nativeElement.childNodes...
}
(未经测试)
答案 5 :(得分:5)
如果要显示默认内容,为什么不使用CSS中的“独生子”选择器。
https://www.w3schools.com/cssref/sel_only-child.asp
例如: HTML
<div>
<ng-content></ng-content>
<div class="default-content">I am deafult</div>
</div>
css
.default-content:not(:only-child) {
display: none;
}
答案 6 :(得分:2)
我已经通过使用 @ContentChildren 装饰器实现了一个解决方案,它在某种程度上类似于@Lerner的答案。
根据docs,此装饰器:
从内容DOM获取元素或指令的QueryList。每当添加,删除或移动子元素时,查询列表都会被更新,并且查询列表中可观察到的更改将发出新值。
因此,父组件中的必要代码将是:
<app-my-component>
<div #myComponentContent>
This is my component content
</div>
</app-my-component>
在组件类中:
@ContentChildren('myComponentContent') content: QueryList<ElementRef>;
然后,在组件模板中:
<div class="container">
<ng-content></ng-content>
<span *ngIf="*ngIf="!content.length""><em>Display this if ng-content is empty!</em></span>
</div>
完整示例:https://stackblitz.com/edit/angular-jjjdqb
我发现此解决方案在form-field组件的matSuffix
的角度组件中实现。
在稍后注入组件的内容的情况下, 应用程序初始化后,我们还可以通过订阅changes
事件来使用响应式实现QueryList
:
export class MyComponentComponent implements AfterContentInit, OnDestroy {
private _subscription: Subscription;
public hasContent: boolean;
@ContentChildren('myComponentContent') content: QueryList<ElementRef>;
constructor() {}
ngAfterContentInit(): void {
this.hasContent = (this.content.length > 0);
this._subscription = this.content.changes.subscribe(() => {
// do something when content updates
//
this.hasContent = (this.content.length > 0);
});
}
ngOnDestroy() {
this._subscription.unsubscribe();
}
}
答案 7 :(得分:2)
使用Angular 10时,它略有变化。您将使用:
<div #ref><ng-content></ng-content></div>
<span *ngIf="ref.children.length == 0">
Display this if ng-content is empty!
</span>
答案 8 :(得分:1)
就我而言,我必须隐藏空白ng-content的父项:
<span class="ml-1 wrapper">
<ng-content>
</ng-content>
</span>
简单的CSS作品:
.wrapper {
display: inline-block;
&:empty {
display: none;
}
}
答案 9 :(得分:1)
在 Angular 12 中,控制台会为我报告以下内容:
<块引用>“HTMLElement”类型不存在属性“nativeElement”
似乎存在可以用于这种情况的特定属性 childElementCount
。
因此,我成功地使用了它,它不会将动态内容包装到其他元素/标签中:
<div class="container">
<!-- some html skipped -->
<ng-container #someContent>
<ng-content></ng-content>
</ng-container>
<span
*ngIf="
someContent.childElementCount === undefined ||
someContent.childElementCount === 0
"
>
Display this if ng-content is empty!
</span>
<!-- some html skipped -->
</div>
答案 10 :(得分:0)
<ng-content #ref></ng-content>
显示错误“ref”未声明。
以下内容适用于 Angular 11(也可能是 10):
<div #ref><ng-content></ng-content></div>
<ng-container *ngIf="!ref.hasChildNodes()">
Default Content
</ng-container>
答案 11 :(得分:0)
在 angular 11 中我使用它并且工作正常。
模板文件:
<h3 class="card-label" #titleBlock>
<ng-content select="[title]" ></ng-content>
</h3>
组件:
@ViewChild('titleBlock') titleBlock: ElementRef;
hasTitle: boolean;
ngAfterViewInit(): void {
if (this.titleBlock && this.titleBlock.nativeElement.innerHTML.trim().length > 0)
{
this.hasTitle= true;
}
else
{
this.hasTitle= false;
}
}