Javascript 在 Angular 2 中如何检查 <ng-content> 是否为空?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35107211/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In Angular 2 how to check whether <ng-content> is empty?
提问by Slawomir Dadas
Suppose I have a component:
假设我有一个组件:
@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 {
}
Now, I would like to display some default content if <ng-content>
for this component is empty. Is there an easy way to do this without accessing the DOM directly?
现在,如果<ng-content>
此组件为空,我想显示一些默认内容。有没有一种简单的方法可以在不直接访问 DOM 的情况下做到这一点?
回答by pixelbits
Wrap ng-content
in an HTML element like a div
to get a local reference to it, then bind the ngIf
expression to ref.children.length == 0
:
包裹ng-content
在像 a 这样的 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>`
回答by lfoma
There some missing in @pixelbits answer. We need to check not only children
property, because any line breaks or spaces in parent template will cause children
element with blank text\linebreaks.
Better to check .innerHTML
and .trim()
it.
@pixelbits 答案中缺少一些内容。我们不仅需要检查children
属性,因为父模板中的任何换行符或空格都会导致children
元素出现空白文本\换行符。更好地检查.innerHTML
和.trim()
它。
Working example:
工作示例:
<span #ref><ng-content></ng-content></span>
<span *ngIf="!ref.innerHTML.trim()">
Content if empty
</span>
回答by Lerner
When you inject the content add a reference variable:
当您注入内容时,添加一个引用变量:
<div #content>Some Content</div>
and in your component class get a reference to the injected content with @ContentChild()
并在您的组件类中使用 @ContentChild() 获取对注入内容的引用
@ContentChild('content') content: ElementRef;
so in your component template you can check if the content variable has a value
所以在你的组件模板中,你可以检查 content 变量是否有值
<div>
<ng-content></ng-content>
<span *ngIf="!content">
Display this if ng-content is empty!
</span>
</div>
回答by Stefan Rein
EDIT 17.03.2020
编辑 17.03.2020
Pure CSS (2 solutions)
纯 CSS(2 个解决方案)
Provides default content if nothing is projected into ng-content.
如果没有任何内容投射到 ng-content 中,则提供默认内容。
Possible selectors:
可能的选择器:
:only-child
selector. See this post here: :only-child SelectorThis one require less code / markup. Support since IE 9: Can I Use :only-child
:empty
selector. Just read further.Support from IE 9 and partially since IE 7/8: https://caniuse.com/#feat=css-sel3
:only-child
选择器。在这里看到这篇文章::only-child Selector这个需要更少的代码/标记。自 IE 9 起支持:我可以使用 :only-child
:empty
选择器。只需进一步阅读。来自 IE 9 和部分自 IE 7/8 的支持:https: //caniuse.com/#feat=css-sel3
HTML
HTML
<div class="wrapper">
<ng-content select="my-component"></ng-content>
</div>
<div class="default">
This shows something default.
</div>
CSS
CSS
.wrapper:not(:empty) + .default {
display: none;
}
In case it's not working
如果它不起作用
Be aware of, that having at least one whitespace is considered to not beeing empty. Angular removes whitespace, but just in case if it is not:
请注意,至少有一个空格被认为不是空的。Angular 会删除空格,但以防万一:
<div class="wrapper"><!--
--><ng-content select="my-component"></ng-content><!--
--></div>
or
或者
<div class="wrapper"><ng-content select="my-component"></ng-content</div>
回答by Günter Z?chbauer
Inject elementRef: ElementRef
and check if elementRef.nativeElement
has any children. This might only work with encapsulation: ViewEncapsulation.Native
.
注射elementRef: ElementRef
并检查是否elementRef.nativeElement
有儿童。这可能只适用于encapsulation: ViewEncapsulation.Native
.
Wrap the <ng-content>
tag and check if it has children. This doesn't work with encapsulation: ViewEncapsulation.Native
.
包裹<ng-content>
标签并检查它是否有孩子。这不适用于encapsulation: ViewEncapsulation.Native
.
<div #contentWrapper>
<ng-content></ng-content>
</div>
and check if it has any children
并检查它是否有任何孩子
@ViewChild('contentWrapper') contentWrapper;
ngAfterViewInit() {
contentWrapper.nativeElement.childNodes...
}
(not tested)
(未测试)
回答by ecosystem31
If you want to display a default content why dont you just use the 'only-child' selector from css.
如果您想显示默认内容,为什么不使用 css 中的“only-child”选择器。
https://www.w3schools.com/cssref/sel_only-child.asp
https://www.w3schools.com/cssref/sel_only-child.asp
for eg: HTML
例如:HTML
<div>
<ng-content></ng-content>
<div class="default-content">I am deafult</div>
</div>
css
css
.default-content {
display: none;
}
.default-content:only-child {
display: block;
}
回答by smg
In my case I have to hide parent of empty ng-content:
在我的情况下,我必须隐藏空 ng-content 的父级:
<span class="ml-1 wrapper">
<ng-content>
</ng-content>
</span>
Simple css works:
简单的css工作:
.wrapper {
display: inline-block;
&:empty {
display: none;
}
}
回答by andreivictor
I've implemented a solution by using @ContentChildrendecorator, that is somehow similar to @Lerner's answer.
我已经通过使用@ContentChildren装饰器实现了一个解决方案,这在某种程度上类似于@Lerner的答案。
According to docs, this decorator:
根据docs,这个装饰器:
Get the QueryList of elements or directives from the content DOM. Any time a child element is added, removed, or moved, the query list will be updated, and the changes observable of the query list will emit a new value.
从内容 DOM 中获取元素或指令的 QueryList。每当添加、删除或移动子元素时,查询列表都会更新,查询列表的可观察更改将发出一个新值。
So the necessary code in the parent component will be:
所以父组件中必要的代码将是:
<app-my-component>
<div #myComponentContent>
This is my component content
</div>
</app-my-component>
In the component class:
在组件类中:
@ContentChildren('myComponentContent') content: QueryList<ElementRef>;
Then, in component template:
然后,在组件模板中:
<div class="container">
<ng-content></ng-content>
<span *ngIf="*ngIf="!content.length""><em>Display this if ng-content is empty!</em></span>
</div>
Full example: https://stackblitz.com/edit/angular-jjjdqb
完整示例:https: //stackblitz.com/edit/angular-jjjdqb
I've found this solution implemented in angular components, for matSuffix
, in the form-fieldcomponent.
我发现这个解决方案在 angular 组件中实现, for matSuffix
,在form-field组件中。
In the situation when the content of the component is injected later on, afterthe app is initialised, we can also use a reactive implementation, by subscribing to the changes
event of the QueryList
:
在稍后注入组件内容的情况下,在应用程序初始化后,我们还可以使用反应式实现,通过订阅以下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();
}
}
Full example: https://stackblitz.com/edit/angular-essvnq