programing

가 비어 있는지 확인하는 방법은 무엇입니까? (앵글 2+에서 지금까지)

newstyles 2023. 5. 24. 21:46

비어 있는지 확인하는 방법은 무엇입니까? (앵글 2+에서 지금까지)

구성 요소가 있다고 가정합니다.

@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에 직접 접속하지 않고 쉽게 할 수 있는 방법이 있습니까?

싼다ng-content같은 HTML 요소에서div로컬 참조를 가져오려면 다음을 바인딩합니다.ngIf에 대한 표현.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>`

Angular 12에 대해 업데이트됨, 이전 로직("ref.nativeElement.childNodes.length") 오류를 표시합니다.nativeElement이라undefined요즘 들어.

2020년 3월 17일 편집

순수 CSS(2개 솔루션)

ng-content에 아무것도 투영되지 않은 경우 기본 컨텐츠를 제공합니다.

가능한 선택기:

  1. :only-child선택자다음 게시물 참조: : 외동 선택기

    이것은 코드/마크업이 덜 필요합니다.IE 9 이후 지원: 사용할 수 있습니까: 외동 자녀

  2. :empty선택자더 읽어보세요.

    IE 9 및 IE 7/8 이후 부분적으로 지원: https://caniuse.com/ #http=http-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;
}

안 될 경우를 대비해서요.

공백이 하나 이상 있으면 비어 있지 않은 것으로 간주됩니다.각도는 공백을 제거하지만 그렇지 않은 경우를 대비하여 다음을 제거합니다.

<div class="wrapper"><!--
    --><ng-content select="my-component"></ng-content><!--
--></div>

또는

<div class="wrapper"><ng-content select="my-component"></ng-content></div>

@pixelbits 답변에 일부 누락이 있습니다.우리는 단지 확인할 필요가 없습니다.children속성. 부모 템플릿의 줄 바꿈 또는 공백으로 인해children공백 텍스트\줄 바꿈이 있는 요소입니다.확인하는 것이 좋습니다..innerHTML그리고..trim()그것.

작업 예제:

<span #ref><ng-content></ng-content></span>
<span *ngIf="!ref.innerHTML.trim()">
    Content if empty
</span>

내용을 주입할 때 참조 변수를 추가합니다.

<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> 

기본 콘텐츠를 표시하고 싶다면 CSS의 '외동' 선택기를 사용하는 것이 어떻습니까?

https://developer.mozilla.org/en-US/docs/Web/CSS/ : 외동딸

fore: HTML

<div>
  <ng-content></ng-content>
  <div class="default-content">I am default</div>
</div>

CSS

.default-content:not(:only-child) {
   display: none;
}

주입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...
}

(테스트되지 않음)

2021년 9월

다음을 사용하여 구현 구성 요소에서 제공되지 않는 경우 기본 콘텐츠를 달성하는 다른 기술이 있습니다.*ngTemplateOutlet사용자 지정을 보다 효과적으로 제어할 수 있도록 하는 지침:

소스 구성 요소의 예:

import { Component, ContentChild, TemplateRef } from '@angular/core';
@Component({
  selector: 'feature-component',
  templateUrl: './feature-component.component.html',
})
export class FeatureComponent {
  @ContentChild('customTemplate') customTemplate: TemplateRef<any>;
}

그런 다음 HTML 템플릿에서:

<ng-container
  [ngTemplateOutlet]="customTemplate || defaultTemplate"
></ng-container>

<ng-template #defaultTemplate>
  <div class="default">
    Default content...
  </div>
</ng-template>

대상 구성 요소:

<!-- default content -->

<feature-component></feature-component>


<!-- dynamic content -->

<feature-component>
  <ng-template #customTemplate>
    <div> Custom group items. </div>
  </ng-template>
</feature-component>

이 경우 빈 ng-content의 상위 항목을 숨겨야 합니다.

<span class="ml-1 wrapper">
  <ng-content>
  </ng-content>
</span>

단순한 css 함수:

.wrapper {
  display: inline-block;

  &:empty {
    display: none;
  }
}

Angular 10으로 약간 변경되었습니다.다음을 사용할 수 있습니다.

<div #ref><ng-content></ng-content></div> 
<span *ngIf="ref.children.length == 0">
  Display this if ng-content is empty!
</span>

는 @ContentChildren decorator를 사용하여 솔루션을 구현했는데, 이는 @Lerner의 답변과 다소 유사합니다.

문서에 따르면 이 장식가는 다음과 같습니다.

DOM 컨텐츠에서 요소 또는 지시어의 쿼리 목록을 가져옵니다.하위 요소가 추가, 제거 또는 이동될 때마다 쿼리 목록이 업데이트되고 쿼리 목록에서 관찰할 수 있는 변경 사항이 새 값을 내보냅니다.

따라서 상위 구성 요소에 필요한 코드는 다음과 같습니다.

<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

저는 이 솔루션이 각진 구성요소에 구현되어 있다는 것을 발견했습니다.matSuffix필드 구성 요소에 있습니다.

나중에 구성 요소의 내용이 주입되는 상황에서 앱 초기화 후에, 우리는 또한 반응형 구현을 사용할 수 있습니다.changesQueryList:

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();
  }

}

전체 예: https://stackblitz.com/edit/angular-essvnq

<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>

Angular 12에서 콘솔은 다음을 보고합니다.

속성 'nativeElement'이(가) 유형 '에 없습니다.HTML 요소'

속성인 특속성존것같다니습는이 하는 것 .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>

각도 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;
    }
}

이 솔루션은 (앵글 버전 12.0.2에서) 저에게 효과가 있었습니다.구성요소가 이미 로드된 후 내용이 동적이고 비어 있는 상태에서 비어 있지 않은 상태(또는 그렇지 않은 상태)로 변경되는 경우에는 이 작업이 수행되지 않을 수 있습니다.변경되는 코드를 추가하여 수정할 수 있습니다.hasContent東京의 ngOnChanges.

예:

import {Component, ViewChild, AfterViewInit} from '@angular/core';

@Component({
    selector: 'my-component',
    template: '<div [ngClass]="[hasContent ? 'has-content' : 'no-content']">
        <span #contentRef>
            <ng-content></ng-content>
        </span>
    </div>']
})
export class Momponent implements AfterViewInit {

    @ViewChild('contentRef', {static: false}) contentRef;

    hasContent: boolean;

    ngAfterViewInit(): void {
        setTimeout(() => {
            this.hasContent = this.contentRef?.nativeElement?.childNodes?.length > 1;
        });
    }
}

두 가지 구성 요소로 나눌 수 있습니다.

@Component({
    selector: 'MyContainer',
    template: `
    <div class="container">
        <!-- some html skipped -->
        <ng-content></ng-content>
        <!-- some html skipped -->
    </div>`
})
export class MyContainer {
}

@Component({
    selector: 'MyContainerNoContent',
    template: `
    <MyContainer>
        <span>Display this if ng-content is empty!</span>
    </MyContainer>`
})
export class MyContainerNoContent {
}

내용을 추가하려면 [내 컨테이너]를 사용하고 기본 내용에 대해 [내 컨테이너 없음]을 사용합니다.

언급URL : https://stackoverflow.com/questions/35107211/how-to-check-whether-ng-content-is-empty-in-angular-2-till-now