ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 06 동적 컴포넌트(Dynamic Component) 02
    앵귤러/03 템플릿&데이터 바인딩 2017. 8. 27. 15:36

    컴포넌트 로딩

    대부분의 광고 배너 구현은 ad-banner.component.ts에 있습니다. 이 예제에서 간단하게하기 위해, HTML @Component 데코레이터의 템플릿 프로퍼티에 템플릿 문자열로 있습니다.

    <ng-template> 엘리먼트는 방금 만든 디렉티브를 적용하는 곳입니다. AdDirective를 적용하려면 ad.directive.ts, ad-host의 셀렉터를 호출하십시오. 대괄호없이 <ng-template>에 적용하십시오. 이제 Angular는 동적으로 컴포넌트를 로드 할 위치를 알고 있습니다.

    src/app/ad-banner.component.ts (template)

    template: `

                <div class="ad-banner">

                  <h3>Advertisements</h3>

                  <ng-template ad-host></ng-template>

                </div>

              `

    <ng-template> 엘리먼트는 추가 출력을 표출하지 않으므로 동적 컴포넌트에 적합합니다.

     

    컴포넌트 해결

    ad-banner.component.ts의 메소드를 자세히 살펴보십시오.

    AdBannerComponent AdItem 객체의 배열을 입력으로 사용하며 궁극적으로 AdService에서 가져옵니다. AdItem 객체는 로드 할 컴포넌트의 유형과 컴포넌트에 바인딩 할 데이터를 지정합니다. AdService는 광고 캠페인을 구성하는 실제 광고를 리턴합니다.

    AdBannerComponent에 컴포넌트 배열을 전달하면 템플릿에 정적 엘리먼트가 없는 광고의 동적 목록이 허용됩니다.

    getAds() 메소드를 사용하면 AdBannerComponent AdItem의 배열을 순환하고 loadComponent()를 호출하여 3 초마다 새 컴포넌트를 로드합니다.

    src/app/ad-banner.component.ts (excerpt)

    export class AdBannerComponent implements AfterViewInit, OnDestroy {

      @Input() ads: AdItem[];

      currentAddIndex: number = -1;

      @ViewChild(AdDirective) adHost: AdDirective;

      subscription: any;

      interval: any;

     

      constructor(private componentFactoryResolver: ComponentFactoryResolver) { }

     

      ngAfterViewInit() {

        this.loadComponent();

        this.getAds();

      }

     

      ngOnDestroy() {

        clearInterval(this.interval);

      }

     

      loadComponent() {

        this.currentAddIndex = (this.currentAddIndex + 1) % this.ads.length;

        let adItem = this.ads[this.currentAddIndex];

     

        let componentFactory = this.componentFactoryResolver.resolveComponentFactory(adItem.component);

     

        let viewContainerRef = this.adHost.viewContainerRef;

        viewContainerRef.clear();

     

        let componentRef = viewContainerRef.createComponent(componentFactory);

        (<AdComponent>componentRef.instance).data = adItem.data;

      }

     

      getAds() {

        this.interval = setInterval(() => {

          this.loadComponent();

        }, 3000);

      }

    }

    loadComponent() 메서드는 여기서 많은 작업을 수행하고 있습니다. 차근차근 확인해 갑니다. 먼저 광고를 선택합니다.

     

    loadComponent()는 광고를 선택한 후 ComponentFactoryResolver를 사용하여 각 특정 컴포넌트에 대한 ComponentFactory를 확인합니다. 그런 다음 ComponentFactory는 각 컴포넌트의 인스턴스를 만듭니다.

    다음으로 이 컴포넌트의 특정 인스턴스에 존재하는 viewContainerRef를 대상으로 지정합니다. 이 특정 인스턴스를 어떻게 알 수 있습니까? 그것은 adHost를 참조하고 있기 때문에 adHost는 이전에 Angular에 동적 컴포넌트를 삽입 할 위치를 지정하기 위해 설정 한 디렉티브입니다.

    AdDirective ViewContainerRef를 생성자에서 주입합니다. 이것은 디렉티브가 동적 컴포넌트를 호스팅하귀 위해 사용할 엘리먼트에 액세스하는 방법입니다.

    컴포넌트를 템플릿에 추가하려면 ViewContainerRef에서 createComponent()를 호출합니다.

    createComponent() 메서드는 로드 된 컴포넌트에 참조를 리턴합니다. 이 참조를 사용하여 프로퍼티에 할당하거나 메서드를 호출하여 컴포넌트와 상호 작용할 수 있습니다.

     

    셀렉터 참조

    일반적으로 Angular 컴파일러는 템플릿에서 참조되는 모든 컴포넌트에 대해 ComponentFactory를 생성합니다. 그러나 동적으로 로드 되는 컴포넌트의 템플릿에는 런타임에 로드되기 때문에 셀렉터 참조가 없습니다.

    컴파일러가 여전히 팩토리를 생성하도록 하려면 동적으로 로드된 컴포넌트를 NgModule entryComponents 배열에 추가합니다.

    src/app/app.module.ts (entry components)

    entryComponents: [ HeroJobAdComponent, HeroProfileComponent ],

     

    댓글

Designed by Tistory.