지시문을 사용하여 뷰포트 크기를 기반으로 콘텐츠 렌더링

이 게시물에서는 구성 요소의 렌더링을 제어하는 ​​구조 지시문을 작성하기 위해 각도를 사용하는 방법을 설명할 것입니다.

구조 지시어는 DOM 요소를 추가 및 제거하여 DOM 레이아웃을 변경하는 지시어입니다. 별표 기호(*)가 앞에 붙습니다. (*ngIf, *ngSwitch...)를 사용했을 수 있습니다.

Detailed explanation here

npm i @angular/cdk // install the angular cdk



import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout'
import { Directive, Input, OnDestroy, TemplateRef, ViewContainerRef } from '@angular/core'
import { Subscription } from 'rxjs'

type BreakpointSizes = 'XSmall' | 'Small' | 'Medium' | 'Large' | 'XLarge' | 'Desktop' | `(${'max-width'|'min-width'}: ${number}px)`

const sizes = new Map([
  ['XSmall', Breakpoints.XSmall],
  ['Small', Breakpoints.Small],
  ['Medium', Breakpoints.Medium],
  ['Large', Breakpoints.Large],
  ['XLarge', Breakpoints.XLarge]
])

@Directive({
  standalone: true,
  selector: '[appIfViewportMatch]'
})
export class IfViewportMatchDirective implements OnDestroy {
  private subscription!: Subscription
  private hasView = false

  constructor(
    private templateRef: TemplateRef<any>,
    private viewContainer: ViewContainerRef,
    private bpObserver: BreakpointObserver
  ) { }

  @Input() set appIfViewportMatch(mq: BreakpointSizes) {
    if (this.subscription) return
    const size = sizes.get(mq)

    this.subscription = this.bpObserver.observe(size || mq).subscribe(({ matches }) => {
      this.render(matches)
    })
  }

  ngOnDestroy(): void {
    this.subscription && this.subscription.unsubscribe()
  }

  private render(matches: boolean) {
    if (!this.hasView && matches) {
      this.viewContainer.createEmbeddedView(this.templateRef)
      this.hasView = true
    } else  {
      this.viewContainer.clear()
      this.hasView = false
    }
  }
}


지시문은 뷰포트 크기를 수신하고 미디어 쿼리가 일치하면 콘텐츠가 DOM으로 렌더링됩니다.

여러 구독을 피하기 위해 첫 번째 세트에서 한 번만 구독합니다.

이 유형은 허용되는 값에 대한 인텔리센스를 제공합니다. 또한 사용자 지정 미디어 쿼리를 제공하는 옵션도 제공합니다.

type BreakpointSizes = 'XSmall' | 'Small' | 'Medium' | 'Large' | 'XLarge' | 'Desktop' | `(${'max-width'|'min-width'}: ${number}px)`


예:

<!-- Only renders when the viewport is more than 600px -->
<hello name="{{ name }}" *appIfViewportMatch="'(min-width: 600px)'"></hello>

<!-- Mobile view -->
<h1 *appIfViewportMatch="'XSmall'">On mobile</h1>


여기에서 작동하는 것을 볼 수 있습니다example.

좋은 웹페이지 즐겨찾기