如何检查ng-content是不是存在[重复]

Posted

技术标签:

【中文标题】如何检查ng-content是不是存在[重复]【英文标题】:How to check whether ng-content exists [duplicate]如何检查ng-content是否存在[重复] 【发布时间】:2016-12-06 04:21:41 【问题描述】:

假设我有一个带有多个嵌入槽的简单引导面板组件。模板示例:

<div class="panel panel-default">
  <div class="panel-heading">
    <ng-content select="my-panel-heading"></ng-content>
  </div>
  <div class="panel-body">
    <ng-content select="my-panel-content"></ng-content>
  </div>
</div>

我想将面板标题设为可选。如果没有为&lt;ng-content select="my-panel-heading"&gt;&lt;/ng-content&gt; 提供内容,我如何隐藏&lt;div class="panel-heading"&gt; 元素

【问题讨论】:

ngIf 应优先于 [hidden]。你喜欢hidden有什么原因吗? @GünterZöchbauer 如果变量 showHeading 初始化为 false,则元素会在调用 ngAfterContentInit 时从模板中删除,从而未定义对 viewChild 的引用。如果首选 ngIf,您可以将 showHeading 的默认值更改为 true,它应该可以工作。 实际上,我只是对其进行了测试,即使将默认值更改为 true,它也无法与 *ngIf 一起使用。对#panelHeading 的引用仍未定义,因为 *ngIf 已将其删除。 没想到。很好的收获。 【参考方案1】:

如果您有一个 &lt;ng-content&gt; 的父元素和一个模板变量 (#panelHeading)

<div class="panel panel-default">
  <div class="panel-heading" #panelHeading [hidden]="!showHeading">
    <ng-content select="my-panel-heading"></ng-content>
  </div>
  <div class="panel-body">
    <ng-content select="my-panel-content"></ng-content>
  </div>
</div>

然后你可以像这样查询它

@ViewChild('panelHeading') panelHeading;

并根据是否有孩子来设置一个属性

constructor(private cdRef:ChangeDetectorRef) 

showHeading:boolean = false;

ngAfterViewInit() 
  this.showHeading = this.panelHeading.nativeElement && this.panelHeading.nativeElement.children.length > 0;
  this.cdRef.detectChanges();

如果&lt;my-panel-heading&gt;是一个Angular2组件,那么你也可以使用

@ContentChild(MyPanelHeading) panelHeading:MyPanelHeading;

constructor(private cdRef:ChangeDetectorRef) 

showHeading:boolean = false;

ngAfterViewInit() 
  this.showHeading = this.panelHeading != null;
  this.cdRef.detectChanges();

【讨论】:

通过将 showHeading 默认值设置为“false”,this.panelHeading 为“未定义”。通过将 showHeading 默认值设置为“true”,它可以正常工作,但我在控制台中得到“ExpressionChangedAfterItHasBeenCheckedError”。此外,我必须使用 'ngAfterViewInit' 而不是 'ngAfterContentInit',否则 showHeading 总是未定义。任何想法如何解决?谢谢 @Luca,感谢您的反馈。我更新了我的答案。我认为现在ngAfterViewInit 是正确的。我更新了一些应该解决你提到的问题的东西。 谢谢!对于我的解决方案,我更喜欢使用*ngIf 而不是hidden,方法是将showHeading 默认值设置为true。现在一切正常:) 有一些生命周期回调,当在此回调中更改模型时,它会导致异常(“模型在检查后已更改”或类似内容)。调用 detectChanges 可修复此异常。 好的,谢谢。我现在对其进行了测试并收到了该错误。并添加 ChangeDetectorRef 修复它。此外,我必须将 showHeading 最初设置为 true 以使我的组件正常工作。【参考方案2】:

您必须删除所有空格,但如果您真的关心它,您可以使用 CSS 执行此操作(ng-content 不占用空间):

.panel-heading:empty  display: none 

<div class="panel-heading"><ng-content select="my-panel-heading"></ng-content></div>

【讨论】:

很好的解决方案。简单高效。 :empty 好甜!谢谢@William Neely。 这不再起作用了...Angular 在最新版本中为我的 div 元素添加了某种 \n。 @muuvmuuv 什么版本? 解决了。我不小心在继承的父组件中有换行符。【参考方案3】:

做:

<div class="panel panel-default">
  <div class="panel-heading" [hidden]="!panelHeading.hasChildNodes()" #panelHeading>
    <ng-content select="my-panel-heading"></ng-content>
  </div>
  <div class="panel-body">
    <ng-content select="my-panel-content"></ng-content>
  </div>
</div>

请注意,在这种情况下,您不能使用 *ngIf,用于 catch-22 情况。

【讨论】:

我不再使用 Angular,但这看起来是最好的答案(如果可行的话) 很好的解决方案。关于*ngIf 的提示是黄金。非常感谢!

以上是关于如何检查ng-content是不是存在[重复]的主要内容,如果未能解决你的问题,请参考以下文章

如何检查 SQL Server 中是不是存在列?

如何检查变量是不是存在[重复]

如何使用 pdo 检查表是不是存在 [重复]

如何检查Mysql表中是不是存在记录[重复]

如何在oracle中检查对象是不是存在[重复]

如何使用 C++ 和 winAPI 检查目录是不是存在 [重复]