가상 드롭다운

    Ignite UI for Angular Drop Down 구성 요소는 선택할 항목의 매우 큰 목록을 표시하기 위해 지시문과 IgxForOf 완전히 통합 될 수 있습니다.

    Angular 가상 드롭 다운 예제

    EXAMPLE
    TS
    HTML
    SCSS

    이 샘플이 마음에 드시나요? 전체 Ignite UI for Angular 툴킷에 액세스하고 몇 분 안에 나만의 앱을 구축해 보세요. 무료로 다운로드하세요.

    용법

    첫 번째 단계

    가상 아이템 목록을 표시하도록 드롭다운을 구성하려면 몇 가지 전제 조건을 충족해야 합니다. 먼저 드롭다운을 선언할 구성 요소의 모듈에서 IgxForOfModule 가져와야 합니다.

    // app.module.ts
    import { IgxForOfModule } from 'igniteui-angular';
    // import { IgxForOfModule } from '@infragistics/igniteui-angular'; for licensed package
    
    @NgModule({
        imports: [
            ...
            IgxForOfModule
        ]
    })
    export class AppModule {}
    typescript

    템플릿 구성

    다음으로 드롭다운 구성요소의 템플릿을 생성하고 다음을 사용하여 데이터를 반복해야 합니다. *igxFor 대신에 *ngFor. 그만큼 *igxFor 모든 항목을 올바르게 표시하려면 지시문에 몇 가지 추가 구성이 필요합니다.

    <!-- drop-down-virtual.component.html -->
    <button igxButton [igxToggleAction]="dropdown"
            [igxDropDownItemNavigation]="dropdown">
            Item Series
    </button>
    <igx-drop-down #dropdown>
        <div class="drop-down-virtual-wrapper" style="height: {{ itemsMaxHeight }}px;">
            <igx-drop-down-item
                *igxFor="let item of items; index as index;
                         scrollOrientation: 'vertical';
                         containerSize: itemsMaxHeight;
                         itemSize: itemHeight;"
                [value]="item" [isHeader]="item.header"
                role="option" [disabled]="item.disabled"
                [index]="index">
                {{ item.name }}
            </igx-drop-down-item>
        </div>
    </igx-drop-down>
    <div>Selected Model: <span>{{ dropdown.selectedItem?.value.name }}</span></div>
    html

    *igxFor 지시문에 전달되는 추가 매개변수는 다음과 같습니다.

    • index- 데이터 세트에서 현재 항목의 인덱스를 캡처합니다.
    • scrollOrientation- 항상 'vertical' 여야 합니다.
    • containerSize- 가상화된 컨테이너의 크기(px 단위)입니다. 이는 <div> 래핑에도 적용되어야 합니다.
    • itemSize- 표시될 항목의 크기(px 단위)

    항목의 고유성을 보장하려면 다음을 통과하십시오. item 내부 value 입력 및 index 내부 index의 입력 igx-drop-down-item. 스크롤하는 동안 선택을 유지하려면 드롭다운 항목에 바인딩된 데이터 항목에 대한 참조가 있어야 합니다.

    드롭다운이 가상화된 항목 목록과 함께 작동하려면 valueindex 입력이 모든 항목에 전달되어야 합니다.

    각 항목에 대해 [value] 입력에 고유한 값을 전달하는 것이 좋습니다. 그렇지 않으면 예상치 못한 결과(잘못된 선택)가 발생할 수 있습니다.

    드롭다운에서 가상화된 항목을 사용하는 경우 dropdown.selectedItem의 유형은 { value: any, index: number }가 됩니다. 여기서 value​ ​[value] 입력 내부에 전달된 데이터 항목에 대한 참조이고 index는 항목의 인덱스입니다. 데이터 세트

    구성 요소 정의

    구성 요소 생성자 내에서 드롭다운에 표시될 적당히 큰 항목 목록(헤더와 비활성화된 항목을 모두 포함)을 선언합니다. itemHeightitemsMaxHeight도 선언해야 합니다.

    // drop-drop-virtual.component.ts
    export class DropDownVirtualComponent {
      public items: DataItem[];
      public itemHeight = 48;
      public itemsMaxHeight = 320;
    
      constructor() {
        const itemsCollection: DataItem[] = [];
        for (let i = 0; i < 50; i++) {
            const series = (i * 10).toString();
            itemsCollection.push({
                id: series,
                name: `${series} Series`,
                header: true,
                disabled: false
            });
            for (let j = 0; j < 10; j++) {
                itemsCollection.push({
                    id: `${series}_${j}`,
                    name: `Series ${series}, ${i * 10 + j} Model`,
                    header: false,
                    disabled: j % 9 === 0
                });
            }
        }
        this.items = itemsCollection;
      }
    }
    typescript

    스타일

    구성의 마지막 부분은 두 개의 스크롤 막대(igxFor에서 하나, 컨테이너 자체에서 하나)가 나타나는 것을 방지하기 위해 래핑 div에 overflow: hidden 설정하는 것입니다.

    // drop-drop-virtual.component.scss
    .drop-down-virtual-wrapper {
      overflow: hidden;
    }
    scss

    원격 데이터

    igx-drop-down​ ​*igxFor 구조 지시문을 사용하여 원격 데이터 청크 로드를 지원합니다. 구성은 로컬 항목의 구성과 유사하며, 주요 차이점은 데이터 청크가 로드되는 방식입니다.

    주형

    드롭다운 템플릿은 이전 예제와 비교했을 때 크게 변경할 필요가 없습니다. 여전히 래핑 div를 지정하고, 그에 따라 스타일을 지정하고, *igxFor에 대한 전체 구성을 작성해야 합니다. 원격 소스에서 데이터를 가져오므로 데이터가 관찰 가능하도록 지정하고 Angular의 async 파이프를 통해 전달해야 합니다.

    <igx-drop-down #remoteDropDown>
        <div class="drop-down-virtual-wrapper">
            <igx-drop-down-item
                *igxFor="let item of rData | async; index as index;
                         scrollOrientation: 'vertical';
                         containerSize: itemsMaxHeight;
                         itemSize: itemHeight;"
                [value]="item.ProductName" role="option"
                [disabled]="item.disabled" [index]="index">
                {{ item.ProductName }}
            </igx-drop-down-item>
        </div>
    </igx-drop-down>
    html

    청크 로드 처리

    보시다시피 템플릿은 이전 예의 템플릿과 거의 동일합니다. 이 원격 데이터 시나리오에서는 뒤에 숨은 코드가 대부분의 무거운 작업을 수행합니다.

    먼저 데이터를 가져오기 위한 원격 서비스를 정의해야 합니다.

    // remote.service.ts
    import { HttpClient } from '@angular/common/http';
    import { Injectable } from '@angular/core';
    import { IForOfState } from 'igniteui-angular';
    // import { IForOfState } from '@infragistics/igniteui-angular'; for licensed package
    import { BehaviorSubject, Observable } from 'rxjs';
    
    @Injectable()
    export class RemoteService {
        public remoteData: Observable<any[]>;
        private _remoteData: BehaviorSubject<any[]>;
    
        constructor(private http: HttpClient) {
            this._remoteData = new BehaviorSubject([]);
            this.remoteData = this._remoteData.asObservable();
        }
    
        public getData(data?: IForOfState, cb?: (any) => void): any {
            // Assuming that the API service is RESTful and can take the following:
            // skip: start index of the data that we fecth
            // count: number of records we fetch
        this.http.get(`https://dummy.db/dummyEndpoint?skip=${data.startIndex}&count=${data.chunkSize}`).subscribe((data) => {
            // emit the values through the _remoteData subject
            this._remoteData.next(data);
        })
    }
    typescript

    이 서비스는 remoteData 아래에 Observable 노출합니다. 서비스를 주입하고 원격 드롭다운 구성 요소에 해당 속성을 바인딩합니다.

    // remote-drop-down.component.ts
    @Component({
        providers: [RemoteService],
        selector: 'app-drop-down-remote',
        templateUrl: './drop-down-remote.component.html',
        styleUrls: ['./drop-down-remote.component.scss']
    })
    export class DropDownRemoteComponent implements OnInit, OnDestroy {
        @ViewChild(IgxForOfDirective, { read: IgxForOfDirective })
        public remoteForDir: IgxForOfDirective<any>;
        @ViewChild('remoteDropDown', { read: IgxDropDownComponent })
        public remoteDropDown: IgxDropDownComponent;
        public itemHeight = 48;
        public itemsMaxHeight = 480;
        public prevRequest: Subscription;
        public rData: any;
    
        private destroy$ = new Subject();
        constructor(private remoteService: RemoteService) { }
    
        public ngAfterViewInit() {
            const initialState = { startIndex: 0, chunkSize: Math.ceil(this.itemsMaxHeight / this.itemHeight) }
            this.remoteService.getData(initialState, (data) => {
                this.remoteForDir.totalItemCount = data['@odata.count'];
            });
            // Subscribe to igxForOf.chunkPreload and load new data from service
            this.remoteForDir.chunkPreload.pipe(takeUntil(this.destroy$)).subscribe((data) => {
                this.dataLoading(data);
            });
        }
    
        public dataLoading(evt) {
            if (this.prevRequest) {
                this.prevRequest.unsubscribe();
            }
            this.prevRequest = this.remoteService.getData(
                evt,
                (data) => {
                    this.remoteForDir.totalItemCount = data['@odata.count'];
                });
        }
    
        public ngOnInit() {
            this.rData = this.remoteService.remoteData;
        }
    
        public ngOnDestroy() {
            this.destroy$.next();
            this.destroy$.complete();
        }
    }
    typescript

    ngAfterViewInit 후크 내에서 초기 상태에 대한 데이터를 가져오고 igxForOf 지시문의 chunkPreload 이미터를 구독하기 위해 호출합니다. 이 구독은 로드된 청크가 변경될 때마다 데이터를 가져오는 역할을 담당합니다. 우리는 pipe(takeUntil(this.destroy$)) 사용하므로 구성 요소 삭제 시 이미터에서 쉽게 구독을 취소할 수 있습니다.

    원격 가상화 - 데모

    위 구성의 결과는 스크롤 막대의 상태에 따라 표시해야 하는 데이터를 동적으로 로드하는 드롭다운입니다.

    EXAMPLE
    TS
    HTML
    SCSS

    참고 및 제한 사항

    가상화된 항목 목록과 함께 드롭다운을 사용하면 몇 가지 제한 사항이 적용됩니다. *igxFor 사용하여 드롭다운 목록을 설정하려고 할 때 다음 사항에 유의하십시오.

    • 반복되는 드롭다운 항목은 다음 CSS가 포함된 래핑 요소(예: <div>)로 전달되어야 합니다. overflow: hiddenheight​ ​px 단위의 containerSize 크기와 같습니다.
    • <igx-drop-down-item-group> 목록이 가상화된 경우 항목을 그룹화하는 데 사용할 수 없습니다. isHeader 대신 속성을 사용하십시오.
    • items 접근자는 현재 가상화된 보기에 있는 헤더가 아닌 드롭다운 항목의 목록만 반환합니다.
    • dropdown.selectedItem{ value: any, index: number } 유형입니다.
    • selection 항목에 의해 방출된 객체 const emittedEvent: { newSelection: { value: any, index: number }, oldSelection: { value: any, index: number }, cancel: boolean, }
    • dropdown.setSelectedItem​ ​데이터 세트의 항목 색인으로 호출되어야 합니다.
    • 드롭다운 항목의 [selected] 입력을 설정하면 드롭다운 선택 항목에 항목이 표시되지 않습니다.
    App Builder | CTA 배너

    API 참조