[]
        
(Showing Draft Content)

가상화 기능 활성화

데이터 가상화가 가능한 RestCollectionView

가상화는 대규모 데이터셋을 처리하는 효과적인 방법으로, 데이터를 요청할 때 가상화하여 처리합니다. 이는 방대한 컬렉션을 다룰 때 특히 유용하며, 모든 데이터를 한 번에 로드하는 것이 비효율적일 때 사용됩니다. RestCollectionView클래스를 확장하여 VirtualRestCollectionView라는 사용자 정의 클래스를 생성하고, virtualization 속성을 true로 설정하면 데이터 소스와 연결하여 데이터를 청크 단위로 로드할 수 있습니다.

지원되는 기능

  • 가상화: 데이터를 필요에 따라 청크 단위로 효율적으로 가져와 메모리 사용량을 줄이고 성능을 향상시킵니다.

  • 서버 측 필터링 및 정: 필터링과 정렬을 서버 측에서 적용하여 필요한 데이터만을 가져옵니다.

type=info

이 기능은 FlexGrid, FlexSheet, MultiRow에서 지원됩니다.

RestCollectionView 확장

가상화 기능을 사용하려면 변수를 초기화하고, 데이터를 필요에 따라 가져오기 위해 getItems 메서드를 재정의해야 합니다.

import { RestCollectionView } from '@mescius/wijmo.rest';
import {copy,httpRequest,asNumber} from "@mescius/wijmo";

export class VirtualRestCollectionView extends RestCollectionView{
    _url: string;
     /**
     * 
     * @param url: The endpoint URL for the REST API.
     * @param options: Optional configuration parameters that can be passed during instantiation.
     */
    constructor(url, options?) {
        super();
        this.groupOnServer = false;
        this.virtualization = true;
        this._url = url;
        copy(this, options);
    }
}

서버에서 받은 데이터는 문자열 형식의 날짜를 포함하고 있으며, 이를 JavaScript의 Date 객체로 변환하려면 JSON Reviver 메서드가 필요합니다.

// parse data
    protected _jsonReviver(key: string, value: any): any {
        const _rxDate = /^\d{4}\-\d{2}\-\d{2}T\d{2}\:\d{2}\:\d{2}|\/Date\([\d\-]*?\)/;
        if (typeof value === 'string' && _rxDate.test(value)) {
            value = value.indexOf('/Date(') == 0 // verbosejson
                ? new Date(parseInt(value.substr(6)))
                : new Date(value);
        }
        return value;
    }

서버에 데이터를 요청하기 전에 요청 파라미터를 준비해야 합니다. 이를 위해 _getReadParams메서드를 다음과 같은 파라미터로 작성합니다:

  • 필터링: 필터 기준을 OData 형식으로 변환하여 요청에 적용합니다.

  • 정렬: 정렬 설명을 바탕으로 order-by 절을 구성합니다.

  • 가상화: 효율적인 데이터 페이지 처리를 위해 요청에 skiptop 파라미터를 추가합니다.

_getReadParams(): any {
        let settings: any = {};
        // apply filter 
        if (this.filterOnServer && this._filterProvider) {
            let filter = this._asODataFilter(this._filterProvider);
            if (filter.length > 0) {
                settings.filterBy = filter;
            }
        }
        //apply orderBy
        if (this.sortDescriptions.length > 0) {
            let _sortBy = [];
            for (let i = 0; i < this.sortDescriptions.length; i++) {
                let sort = `${this.sortDescriptions[i].property} ${this.sortDescriptions[i].ascending ? 'ASC' : 'DESC'}`;
                _sortBy.push(sort);// add sort
            }
            settings.orderBy = _sortBy.join(',');
        }
        // 
        if (this.virtualization) {
            settings.skip = this._start;
            settings.top = this._fetchSize();
        }
        return settings;
    }

type=info

필터는 _asODataFilter 함수를 사용하여 OData 형식으로 변환됩니다. 만약 데이터 소스가 ODataFormat을 지원하지 않는다면, 필터 쿼리를 데이터 소스에서 허용하는 형식으로 변환하는 사용자 정의 메서드를 만들 수 있습니다.

_asODataFilter 메서드 코드는 RestCollectionView\OData 데모 샘플의 rest-collection-view-odata.js 파일에서 가져올 수 있습니다.

요청 파라미터가 준비되었으므로 이제 서버에 데이터를 요청할 준비가 되었습니다. 이를 위해 getItems메서드를 재정의하게 됩니다.

protected getItems(): Promise<any[]> {
        // cancel any pending requests
        if (this._pendingReq) {
            this._pendingReq.abort();
        }
        return new Promise<any>(resolve => {
            let _settings = this._getReadParams(); // get the items virtually 
            this._pendingReq = httpRequest(this._url, {
                requestHeaders: this.requestHeaders,
                data: _settings,
                success: async xhr => {
                    // parse response
                    let resp = JSON.parse(xhr.responseText, this._jsonReviver);
                    let _count = asNumber(resp.totalItemCount);
                    if (_count != this._totalItemCount)
                        this._totalItemCount = _count;
                    resolve(resp.items);
                },
                error: xhr => this._raiseError(xhr.responseText, false),
                complete: xhr => { this._pendingReq = null; }// no pending requests
            });
        });;
    }

이제 JavaScript 파일에서 RESTCollectionView를 호출하여 FlexGrid 컨트롤의 데이터 소스로 사용할 수 있습니다.:

// Extended RESTCollectionView class
import { VirtualRestCollectionView } from './virtual-rest-collection-view';
import { FlexGrid } from '@mescius/wijmo.grid';
function init(){
  let cv =  new VirtualRestCollectionView(url); // create CollectionView Instance
  let grid = new FlexGrid("#virtualGrid", {
        autoGenerateColumns: false,
        columns: [
            { binding: 'productId', header: 'Product ID', width: '*' },
            { binding: 'color', header: 'Color', width: '*' },
            { binding: 'modifiedDate', header: 'Modified Date', dataType: 'Date', format: 'd' },
            { binding: 'quantity', header: 'Quantity', dataType: 'Number', format: 'n2' },
            { binding: 'actualCost', header: 'Actual Cost', dataType: 'Number', format: 'n2'}
        ],
        itemsSource:cv // assign Custom Collection View Instance
    });
}

type=info

참고: 페이지네이션은 지원되지 않습니다.

서버 및 클라이언트 코드와 함께 샘플 구현을 확인하려면 Wijmo-Rest-CollectionView-Sample을 참고해주세요.