如果给出 ng-content 如何排除绑定?

How to exclude binding if ng-content given?

我正在尝试创建一个带有自己的 ng-content 的自定义 primeNG 按钮。目标是如果给出了内容,应该使用它来代替标准的 pButton 标签绑定。

这是我为此组件提出的基本代码:

<button pButton [label]="label">
  <ng-content></ng-content>
</button>

这当然会始终显示按钮中提供的标签和 ng-content。我只想在未提供内容时查看标签。

我已经解决了这个问题的几个问题,包括尝试集成 ngIf、使用 ViewChild 检查 ng-content 是否存在等。任何帮助将不胜感激。

您可以使用 viewchild 获取容器的引用,并检查元素是否已经包含内容,并以此为基础设置传递的标签值或自定义组件的投影值,如下所示

客户组件将如下所示

@Component({
  selector: 'c-btn',
  templateUrl: './btn.component.html',
  styleUrls: ['./btn.component.css']
})
export class BtnComponent  {

  @Input('label') staticLabel : string= "";

  @ViewChild('content') projectedLabel: ElementRef;

  get label () :string{
    return  this.projectedLabel.nativeElement.innerHTML.trim() || this.staticLabel
  }

}

模板

<button pButton [label]="label" ></button>

<div #content style="display:none">
    <ng-content ></ng-content>
</div>

demo

puting ng-content outside the button elemnt make it easer to check if it 's got a value or not, another reasone why you have to put ng-content outside the button elemnt it related to primeng , pButton has some kind of structure in order the button will view as intated so in both cases you need use property binding with the label property

另一种方式

这可能是最简单的解决方案,方法是使用模板变量并检查元素是否有内容。

客户元素

<button pButton [label]="content.innerHTML || label" ></button>

<div #content style="display:none">
    <ng-content ></ng-content>
</div>

组件

export class BtnComponent  {

  @Input() label : string= "";  
}

demo

更新了⚡⚡

这将支持投影为 html 元素,而不仅仅是通过按钮内的更新跨度作为按钮的文本

组件

  @Input('label') label : string= "";

  @ViewChild('content') projectedLabel: ElementRef;
  @ViewChild('btn') button: ElementRef;

  ngAfterViewInit(){
    if (this.projectedLabel.nativeElement.innerHTML){
       const elm = this.button.nativeElement.querySelector('span');
        elm.innerHTML =  this.projectedLabel.nativeElement.innerHTML;
    }
  }

模板

<button pButton [label]="label" #btn></button>

<div #content style="display:none">
    <ng-content ></ng-content>
</div>

demo