javascript - Làm thế nào để kiểm tra xem <ng-content> có trống không? (trong Angular 2+ đến nay)
Giả sử tôi có một thành phần:
@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 {
}
Bây giờ, tôi muốn hiển thị một số nội dung mặc định nếu <ng-content> cho thành phần này trống. Có cách nào dễ dàng để làm điều này mà không cần truy cập trực tiếp vào DOM không?
Câu trả lời #1
Đặt ng-content trong một phần tử HTML như div để có một tham chiếu cục bộ tới nó, sau đó liên kết biểu thức ngIf với ref.children.length == 0:
template: `<div #ref><ng-content></ng-content></div>
<span *ngIf=" ! ref.children.length">
Display this if ng-content is empty!
</span>`
Cập nhật cho Angular 12; logic cũ ("
ref.nativeElement.childNodes.length") gây lỗi, vìnativeElementhiện nay làundefined.
Câu trả lời #2
CHỈNH SỬA 17.03.2020
CSS thuần (2 giải pháp)
Cung cấp nội dung mặc định nếu không có gì được chiếu vào ng-content.
Các bộ chọn có thể:
Bộ chọn
:only-child. Xem bài viết này tại đây: Bộ chọn :only-childCái này yêu cầu ít mã/đánh dấu hơn. Hỗ trợ từ IE 9: Tôi có thể sử dụng :only-child không
Bộ chọn
:empty. Chỉ cần đọc tiếp.Hỗ trợ từ IE 9 và một phần kể từ IE 7/8: https://caniuse.com/#feat=css-sel3
HTML
<div class="wrapper">
<ng-content select="my-component"></ng-content>
</div>
<div class="default">
This shows something default.
</div>
CSS
.wrapper:not(:empty) + .default {
display: none;
}
Trong trường hợp nó không hoạt động
Hãy lưu ý rằng, việc có ít nhất một khoảng trắng được coi là không rỗng. Angular sẽ loại bỏ khoảng trắng, nhưng chỉ trong trường hợp nó không bị loại:
<div class="wrapper"><!--
--><ng-content select="my-component"></ng-content><!--
--></div>
hoặc
<div class="wrapper"><ng-content select="my-component"></ng-content></div>
Câu trả lời #3
Có một số điều thiếu trong câu trả lời của @pixelbits. Chúng ta cần kiểm tra không chỉ thuộc tính children, vì bất kỳ ngắt dòng hoặc khoảng trắng nào trong template cha sẽ tạo ra phần tử children với văn bản trống hoặc ngắt dòng. Tốt hơn nên kiểm tra .innerHTML và dùng .trim() cho nó.
Ví dụ thực tế:
<span #ref><ng-content></ng-content></span>
<span *ngIf="!ref.innerHTML.trim()">
Content if empty
</span>
Câu trả lời #4
Khi bạn chèn nội dung, hãy thêm một biến tham chiếu:
<div #content>Some Content</div>
và trong lớp component của bạn, lấy một tham chiếu đến nội dung được tiêm với @ContentChild()
@ContentChild('content') content: ElementRef;
vì vậy trong mẫu thành phần của bạn, bạn có thể kiểm tra xem biến content có giá trị hay không
<div>
<ng-content></ng-content>
<span *ngIf="!content">
Display this if ng-content is empty!
</span>
</div>
Câu trả lời số 5
Nếu bạn muốn hiển thị nội dung mặc định, tại sao bạn không chỉ sử dụng bộ chọn 'only-child' từ CSS.
https://developer.mozilla.org/vi/docs/Web/CSS/:only-child
ví dụ: HTML
<div>
<ng-content></ng-content>
<div class="default-content">I am default</div>
</div>
CSS
.default-content:not(:only-child) {
display: none;
}
Câu trả lời số 6
Tiêm elementRef: ElementRef và kiểm tra xem elementRef.nativeElement có bất kỳ phần tử con nào không. Điều này có thể chỉ hoạt động với encapsulation: ViewEncapsulation.Native.
Bao bọc thẻ <ng-content> và kiểm tra xem nó có phần tử con hay không. Điều này không hoạt động với encapsulation: ViewEncapsulation.Native.
<div #contentWrapper>
<ng-content></ng-content>
</div>
và kiểm tra xem nó có bất kỳ con nào không
@ViewChild('contentWrapper') contentWrapper;
ngAfterViewInit() {
contentWrapper.nativeElement.childNodes...
}
(chưa được thử nghiệm)
Câu trả lời số 7
Tháng 9 năm 2021
Có một kỹ thuật khác để hoàn thành nội dung mặc định nếu không được cung cấp từ thành phần triển khai bằng cách sử dụng chỉ thị *ngTemplateOutlet cho phép chúng ta có nhiều kiểm soát hơn đối với việc tùy chỉnh:
Ví dụ trong thành phần nguồn:
import { Component, ContentChild, TemplateRef } from '@angular/core';
@Component({
selector: 'feature-component',
templateUrl: './feature-component.component.html',
})
export class FeatureComponent {
@ContentChild('customTemplate') customTemplate: TemplateRef<any>;
}
Sau đó trong mẫu HTML:
<ng-container
[ngTemplateOutlet]="customTemplate || defaultTemplate"
></ng-container>
<ng-template #defaultTemplate>
<div class="default">
Default content...
</div>
</ng-template>
thành phần mục tiêu:
<!-- default content -->
<feature-component></feature-component>
<!-- dynamic content -->
<feature-component>
<ng-template #customTemplate>
<div> Custom group items. </div>
</ng-template>
</feature-component>
