Web Components 그리드 원격 데이터 운영
기본적으로 IgcGridComponent
는 데이터 작업을 수행하기 위해 자체 로직을 사용합니다.
IgcGridComponent
에 의해 노출되는 특정 입력 및 이벤트를 활용하여 이러한 작업을 원격으로 수행하고 결과 데이터를 IgcGridComponent
에 공급할 수 있습니다.
Infinite Scroll
끝점에서 청크로 데이터를 가져와야 하는 시나리오에 널리 사용되는 디자인은 소위 무한 스크롤입니다. 데이터 그리드의 경우 최종 사용자가 맨 아래까지 스크롤하면 로드된 데이터가 지속적으로 증가하는 것이 특징입니다. 다음 단락에서는 사용 가능한 API를 사용하여 IgcGridComponent
에서 무한 스크롤을 쉽게 달성하는 방법을 설명합니다.
무한 스크롤을 구현하려면 데이터를 청크로 가져와야 합니다. 이미 가져온 데이터는 로컬에 저장되어야 하며 청크의 길이와 청크 수를 결정해야 합니다. 또한 그리드에서 마지막으로 표시되는 데이터 행 인덱스를 추적해야 합니다. 이런 방식으로 StartIndex
및 ChunkSize
속성을 사용하면 사용자가 위로 스크롤하여 이미 가져온 데이터를 표시해야 하는지 아니면 아래로 스크롤하여 끝점에서 더 많은 데이터를 가져와야 하는지 결정할 수 있습니다.
가장 먼저 할 일은 데이터의 첫 번째 청크를 가져오는 것입니다. totalItemCount
이 속성을 설정하면 그리드에서 스크롤 막대의 크기를 올바르게 조정할 수 있으므로 중요합니다.
또한 그리드가 현재 로드된 청크가 아닌 다른 청크를 표시하려고 할 때 그리드에 필요한 데이터를 제공할 수 있도록 출력을 구독 DataPreLoad
해야 합니다. 이벤트 처리기에서 새 데이터를 가져올지 아니면 이미 로컬에 캐시된 데이터를 반환할지 여부를 결정해야 합니다.
Infinite Scroll Demo
export class NwindDataItem {
public constructor(init: Partial<NwindDataItem>) {
Object.assign(this, init);
}
public ProductID: number;
public ProductName: string;
public SupplierID: number;
public CategoryID: number;
public QuantityPerUnit: string;
public UnitPrice: number;
public UnitsInStock: number;
public UnitsOnOrder: number;
public ReorderLevel: number;
public Discontinued: boolean;
public OrderDate: string;
public Rating: number;
public Locations: NwindDataItem_LocationsItem[];
}
export class NwindDataItem_LocationsItem {
public constructor(init: Partial<NwindDataItem_LocationsItem>) {
Object.assign(this, init);
}
public Shop: string;
public LastInventory: string;
}
export class NwindData extends Array<NwindDataItem> {
public constructor() {
super();
this.push(new NwindDataItem({ "ProductID": 1, "ProductName": "Chai", "SupplierID": 1, "CategoryID": 1, "QuantityPerUnit": "10 boxes x 20 bags", "UnitPrice": 18.0000, "UnitsInStock": 39, "UnitsOnOrder": 0, "ReorderLevel": 10, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 2, "ProductName": "Chang", "SupplierID": 1, "CategoryID": 1, "QuantityPerUnit": "24 - 12 oz bottles", "UnitPrice": 19.0000, "UnitsInStock": 17, "UnitsOnOrder": 40, "ReorderLevel": 25, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 3, "ProductName": "Aniseed Syrup", "SupplierID": 1, "CategoryID": 2, "QuantityPerUnit": "12 - 550 ml bottles", "UnitPrice": 10.0000, "UnitsInStock": 13, "UnitsOnOrder": 70, "ReorderLevel": 25, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 4, "ProductName": "Chef Anton's Cajun Seasoning", "SupplierID": 2, "CategoryID": 2, "QuantityPerUnit": "48 - 6 oz jars", "UnitPrice": 22.0000, "UnitsInStock": 53, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 5, "ProductName": "Chef Anton's Gumbo Mix", "SupplierID": 2, "CategoryID": 2, "QuantityPerUnit": "36 boxes", "UnitPrice": 21.3500, "UnitsInStock": 0, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": true }));
this.push(new NwindDataItem({ "ProductID": 6, "ProductName": "Grandma's Boysenberry Spread", "SupplierID": 3, "CategoryID": 2, "QuantityPerUnit": "12 - 8 oz jars", "UnitPrice": 25.0000, "UnitsInStock": 120, "UnitsOnOrder": 0, "ReorderLevel": 25, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 7, "ProductName": "Uncle Bob's Organic Dried Pears", "SupplierID": 3, "CategoryID": 7, "QuantityPerUnit": "12 - 1 lb pkgs.", "UnitPrice": 30.0000, "UnitsInStock": 15, "UnitsOnOrder": 0, "ReorderLevel": 10, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 8, "ProductName": "Northwoods Cranberry Sauce", "SupplierID": 3, "CategoryID": 2, "QuantityPerUnit": "12 - 12 oz jars", "UnitPrice": 40.0000, "UnitsInStock": 6, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 9, "ProductName": "Mishi Kobe Niku", "SupplierID": 4, "CategoryID": 6, "QuantityPerUnit": "18 - 500 g pkgs.", "UnitPrice": 97.0000, "UnitsInStock": 29, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": true }));
this.push(new NwindDataItem({ "ProductID": 10, "ProductName": "Ikura", "SupplierID": 4, "CategoryID": 8, "QuantityPerUnit": "12 - 200 ml jars", "UnitPrice": 31.0000, "UnitsInStock": 31, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 11, "ProductName": "Queso Cabrales", "SupplierID": 5, "CategoryID": 4, "QuantityPerUnit": "1 kg pkg.", "UnitPrice": 21.0000, "UnitsInStock": 22, "UnitsOnOrder": 30, "ReorderLevel": 30, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 12, "ProductName": "Queso Manchego La Pastora", "SupplierID": 5, "CategoryID": 4, "QuantityPerUnit": "10 - 500 g pkgs.", "UnitPrice": 38.0000, "UnitsInStock": 86, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 13, "ProductName": "Konbu", "SupplierID": 6, "CategoryID": 8, "QuantityPerUnit": "2 kg box", "UnitPrice": 6.0000, "UnitsInStock": 24, "UnitsOnOrder": 0, "ReorderLevel": 5, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 14, "ProductName": "Tofu", "SupplierID": 6, "CategoryID": 7, "QuantityPerUnit": "40 - 100 g pkgs.", "UnitPrice": 23.2500, "UnitsInStock": 35, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 15, "ProductName": "Genen Shouyu", "SupplierID": 6, "CategoryID": 2, "QuantityPerUnit": "24 - 250 ml bottles", "UnitPrice": 15.5000, "UnitsInStock": 39, "UnitsOnOrder": 0, "ReorderLevel": 5, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 16, "ProductName": "Pavlova", "SupplierID": 7, "CategoryID": 3, "QuantityPerUnit": "32 - 500 g boxes", "UnitPrice": 17.4500, "UnitsInStock": 29, "UnitsOnOrder": 0, "ReorderLevel": 10, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 17, "ProductName": "Alice Mutton", "SupplierID": 7, "CategoryID": 6, "QuantityPerUnit": "20 - 1 kg tins", "UnitPrice": 39.0000, "UnitsInStock": 0, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": true }));
this.push(new NwindDataItem({ "ProductID": 18, "ProductName": "Carnarvon Tigers", "SupplierID": 7, "CategoryID": 8, "QuantityPerUnit": "16 kg pkg.", "UnitPrice": 62.5000, "UnitsInStock": 42, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 19, "ProductName": "Teatime Chocolate Biscuits", "SupplierID": 8, "CategoryID": 3, "QuantityPerUnit": "10 boxes x 12 pieces", "UnitPrice": 9.2000, "UnitsInStock": 25, "UnitsOnOrder": 0, "ReorderLevel": 5, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 20, "ProductName": "Sir Rodney's Marmalade", "SupplierID": 8, "CategoryID": 3, "QuantityPerUnit": "30 gift boxes", "UnitPrice": 81.0000, "UnitsInStock": 40, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 21, "ProductName": "Sir Rodney's Scones", "SupplierID": 8, "CategoryID": 3, "QuantityPerUnit": "24 pkgs. x 4 pieces", "UnitPrice": 10.0000, "UnitsInStock": 3, "UnitsOnOrder": 40, "ReorderLevel": 5, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 22, "ProductName": "Gustaf's Kn\u00e4ckebr\u00f6d", "SupplierID": 9, "CategoryID": 5, "QuantityPerUnit": "24 - 500 g pkgs.", "UnitPrice": 21.0000, "UnitsInStock": 104, "UnitsOnOrder": 0, "ReorderLevel": 25, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 23, "ProductName": "Tunnbr\u00f6d", "SupplierID": 9, "CategoryID": 5, "QuantityPerUnit": "12 - 250 g pkgs.", "UnitPrice": 9.0000, "UnitsInStock": 61, "UnitsOnOrder": 0, "ReorderLevel": 25, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 24, "ProductName": "Guaran\u00e1 Fant\u00e1stica", "SupplierID": 10, "CategoryID": 1, "QuantityPerUnit": "12 - 355 ml cans", "UnitPrice": 4.5000, "UnitsInStock": 20, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": true }));
this.push(new NwindDataItem({ "ProductID": 25, "ProductName": "NuNuCa Nu\u00df-Nougat-Creme", "SupplierID": 11, "CategoryID": 3, "QuantityPerUnit": "20 - 450 g glasses", "UnitPrice": 14.0000, "UnitsInStock": 76, "UnitsOnOrder": 0, "ReorderLevel": 30, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 26, "ProductName": "Gumb\u00e4r Gummib\u00e4rchen", "SupplierID": 11, "CategoryID": 3, "QuantityPerUnit": "100 - 250 g bags", "UnitPrice": 31.2300, "UnitsInStock": 15, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 27, "ProductName": "Schoggi Schokolade", "SupplierID": 11, "CategoryID": 3, "QuantityPerUnit": "100 - 100 g pieces", "UnitPrice": 43.9000, "UnitsInStock": 49, "UnitsOnOrder": 0, "ReorderLevel": 30, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 28, "ProductName": "R\u00f6ssle Sauerkraut", "SupplierID": 12, "CategoryID": 7, "QuantityPerUnit": "25 - 825 g cans", "UnitPrice": 45.6000, "UnitsInStock": 26, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": true }));
this.push(new NwindDataItem({ "ProductID": 29, "ProductName": "Th\u00fcringer Rostbratwurst", "SupplierID": 12, "CategoryID": 6, "QuantityPerUnit": "50 bags x 30 sausgs.", "UnitPrice": 123.7900, "UnitsInStock": 0, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": true }));
this.push(new NwindDataItem({ "ProductID": 30, "ProductName": "Nord-Ost Matjeshering", "SupplierID": 13, "CategoryID": 8, "QuantityPerUnit": "10 - 200 g glasses", "UnitPrice": 25.8900, "UnitsInStock": 10, "UnitsOnOrder": 0, "ReorderLevel": 15, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 31, "ProductName": "Gorgonzola Telino", "SupplierID": 14, "CategoryID": 4, "QuantityPerUnit": "12 - 100 g pkgs", "UnitPrice": 12.5000, "UnitsInStock": 0, "UnitsOnOrder": 70, "ReorderLevel": 20, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 32, "ProductName": "Mascarpone Fabioli", "SupplierID": 14, "CategoryID": 4, "QuantityPerUnit": "24 - 200 g pkgs.", "UnitPrice": 32.0000, "UnitsInStock": 9, "UnitsOnOrder": 40, "ReorderLevel": 25, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 33, "ProductName": "Geitost", "SupplierID": 15, "CategoryID": 4, "QuantityPerUnit": "500 g", "UnitPrice": 2.5000, "UnitsInStock": 112, "UnitsOnOrder": 0, "ReorderLevel": 20, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 34, "ProductName": "Sasquatch Ale", "SupplierID": 16, "CategoryID": 1, "QuantityPerUnit": "24 - 12 oz bottles", "UnitPrice": 14.0000, "UnitsInStock": 111, "UnitsOnOrder": 0, "ReorderLevel": 15, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 35, "ProductName": "Steeleye Stout", "SupplierID": 16, "CategoryID": 1, "QuantityPerUnit": "24 - 12 oz bottles", "UnitPrice": 18.0000, "UnitsInStock": 20, "UnitsOnOrder": 0, "ReorderLevel": 15, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 36, "ProductName": "Inlagd Sill", "SupplierID": 17, "CategoryID": 8, "QuantityPerUnit": "24 - 250 g jars", "UnitPrice": 19.0000, "UnitsInStock": 112, "UnitsOnOrder": 0, "ReorderLevel": 20, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 37, "ProductName": "Gravad lax", "SupplierID": 17, "CategoryID": 8, "QuantityPerUnit": "12 - 500 g pkgs.", "UnitPrice": 26.0000, "UnitsInStock": 11, "UnitsOnOrder": 50, "ReorderLevel": 25, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 38, "ProductName": "C\u00f4te de Blaye", "SupplierID": 18, "CategoryID": 1, "QuantityPerUnit": "12 - 75 cl bottles", "UnitPrice": 263.5000, "UnitsInStock": 17, "UnitsOnOrder": 0, "ReorderLevel": 15, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 39, "ProductName": "Chartreuse verte", "SupplierID": 18, "CategoryID": 1, "QuantityPerUnit": "750 cc per bottle", "UnitPrice": 18.0000, "UnitsInStock": 69, "UnitsOnOrder": 0, "ReorderLevel": 5, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 40, "ProductName": "Boston Crab Meat", "SupplierID": 19, "CategoryID": 8, "QuantityPerUnit": "24 - 4 oz tins", "UnitPrice": 18.4000, "UnitsInStock": 123, "UnitsOnOrder": 0, "ReorderLevel": 30, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 41, "ProductName": "Jack's New England Clam Chowder", "SupplierID": 19, "CategoryID": 8, "QuantityPerUnit": "12 - 12 oz cans", "UnitPrice": 9.6500, "UnitsInStock": 85, "UnitsOnOrder": 0, "ReorderLevel": 10, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 42, "ProductName": "Singaporean Hokkien Fried Mee", "SupplierID": 20, "CategoryID": 5, "QuantityPerUnit": "32 - 1 kg pkgs.", "UnitPrice": 14.0000, "UnitsInStock": 26, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": true }));
this.push(new NwindDataItem({ "ProductID": 43, "ProductName": "Ipoh Coffee", "SupplierID": 20, "CategoryID": 1, "QuantityPerUnit": "16 - 500 g tins", "UnitPrice": 46.0000, "UnitsInStock": 17, "UnitsOnOrder": 10, "ReorderLevel": 25, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 44, "ProductName": "Gula Malacca", "SupplierID": 20, "CategoryID": 2, "QuantityPerUnit": "20 - 2 kg bags", "UnitPrice": 19.4500, "UnitsInStock": 27, "UnitsOnOrder": 0, "ReorderLevel": 15, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 45, "ProductName": "Rogede sild", "SupplierID": 21, "CategoryID": 8, "QuantityPerUnit": "1k pkg.", "UnitPrice": 9.5000, "UnitsInStock": 5, "UnitsOnOrder": 70, "ReorderLevel": 15, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 46, "ProductName": "Spegesild", "SupplierID": 21, "CategoryID": 8, "QuantityPerUnit": "4 - 450 g glasses", "UnitPrice": 12.0000, "UnitsInStock": 95, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 47, "ProductName": "Zaanse koeken", "SupplierID": 22, "CategoryID": 3, "QuantityPerUnit": "10 - 4 oz boxes", "UnitPrice": 9.5000, "UnitsInStock": 36, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 48, "ProductName": "Chocolade", "SupplierID": 22, "CategoryID": 3, "QuantityPerUnit": "10 pkgs.", "UnitPrice": 12.7500, "UnitsInStock": 15, "UnitsOnOrder": 70, "ReorderLevel": 25, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 49, "ProductName": "Maxilaku", "SupplierID": 23, "CategoryID": 3, "QuantityPerUnit": "24 - 50 g pkgs.", "UnitPrice": 20.0000, "UnitsInStock": 10, "UnitsOnOrder": 60, "ReorderLevel": 15, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 50, "ProductName": "Valkoinen suklaa", "SupplierID": 23, "CategoryID": 3, "QuantityPerUnit": "12 - 100 g bars", "UnitPrice": 16.2500, "UnitsInStock": 65, "UnitsOnOrder": 0, "ReorderLevel": 30, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 51, "ProductName": "Manjimup Dried Apples", "SupplierID": 24, "CategoryID": 7, "QuantityPerUnit": "50 - 300 g pkgs.", "UnitPrice": 53.0000, "UnitsInStock": 20, "UnitsOnOrder": 0, "ReorderLevel": 10, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 52, "ProductName": "Filo Mix", "SupplierID": 24, "CategoryID": 5, "QuantityPerUnit": "16 - 2 kg boxes", "UnitPrice": 7.0000, "UnitsInStock": 38, "UnitsOnOrder": 0, "ReorderLevel": 25, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 53, "ProductName": "Perth Pasties", "SupplierID": 24, "CategoryID": 6, "QuantityPerUnit": "48 pieces", "UnitPrice": 32.8000, "UnitsInStock": 0, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": true }));
this.push(new NwindDataItem({ "ProductID": 54, "ProductName": "Tourti\u00e8re", "SupplierID": 25, "CategoryID": 6, "QuantityPerUnit": "16 pies", "UnitPrice": 7.4500, "UnitsInStock": 21, "UnitsOnOrder": 0, "ReorderLevel": 10, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 55, "ProductName": "P\u00e2t\u00e9 chinois", "SupplierID": 25, "CategoryID": 6, "QuantityPerUnit": "24 boxes x 2 pies", "UnitPrice": 24.0000, "UnitsInStock": 115, "UnitsOnOrder": 0, "ReorderLevel": 20, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 56, "ProductName": "Gnocchi di nonna Alice", "SupplierID": 26, "CategoryID": 5, "QuantityPerUnit": "24 - 250 g pkgs.", "UnitPrice": 38.0000, "UnitsInStock": 21, "UnitsOnOrder": 10, "ReorderLevel": 30, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 57, "ProductName": "Ravioli Angelo", "SupplierID": 26, "CategoryID": 5, "QuantityPerUnit": "24 - 250 g pkgs.", "UnitPrice": 19.5000, "UnitsInStock": 36, "UnitsOnOrder": 0, "ReorderLevel": 20, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 58, "ProductName": "Escargots de Bourgogne", "SupplierID": 27, "CategoryID": 8, "QuantityPerUnit": "24 pieces", "UnitPrice": 13.2500, "UnitsInStock": 62, "UnitsOnOrder": 0, "ReorderLevel": 20, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 59, "ProductName": "Raclette Courdavault", "SupplierID": 28, "CategoryID": 4, "QuantityPerUnit": "5 kg pkg.", "UnitPrice": 55.0000, "UnitsInStock": 79, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 60, "ProductName": "Camembert Pierrot", "SupplierID": 28, "CategoryID": 4, "QuantityPerUnit": "15 - 300 g rounds", "UnitPrice": 34.0000, "UnitsInStock": 19, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 61, "ProductName": "Sirop d'\u00e9rable", "SupplierID": 29, "CategoryID": 2, "QuantityPerUnit": "24 - 500 ml bottles", "UnitPrice": 28.5000, "UnitsInStock": 113, "UnitsOnOrder": 0, "ReorderLevel": 25, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 62, "ProductName": "Tarte au sucre", "SupplierID": 29, "CategoryID": 3, "QuantityPerUnit": "48 pies", "UnitPrice": 49.3000, "UnitsInStock": 17, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 63, "ProductName": "Vegie-spread", "SupplierID": 7, "CategoryID": 2, "QuantityPerUnit": "15 - 625 g jars", "UnitPrice": 43.9000, "UnitsInStock": 24, "UnitsOnOrder": 0, "ReorderLevel": 5, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 64, "ProductName": "Wimmers gute Semmelkn\u00f6del", "SupplierID": 12, "CategoryID": 5, "QuantityPerUnit": "20 bags x 4 pieces", "UnitPrice": 33.2500, "UnitsInStock": 22, "UnitsOnOrder": 80, "ReorderLevel": 30, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 65, "ProductName": "Louisiana Fiery Hot Pepper Sauce", "SupplierID": 2, "CategoryID": 2, "QuantityPerUnit": "32 - 8 oz bottles", "UnitPrice": 21.0500, "UnitsInStock": 76, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 66, "ProductName": "Louisiana Hot Spiced Okra", "SupplierID": 2, "CategoryID": 2, "QuantityPerUnit": "24 - 8 oz jars", "UnitPrice": 17.0000, "UnitsInStock": 4, "UnitsOnOrder": 100, "ReorderLevel": 20, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 67, "ProductName": "Laughing Lumberjack Lager", "SupplierID": 16, "CategoryID": 1, "QuantityPerUnit": "24 - 12 oz bottles", "UnitPrice": 14.0000, "UnitsInStock": 52, "UnitsOnOrder": 0, "ReorderLevel": 10, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 68, "ProductName": "Scottish Longbreads", "SupplierID": 8, "CategoryID": 3, "QuantityPerUnit": "10 boxes x 8 pieces", "UnitPrice": 12.5000, "UnitsInStock": 6, "UnitsOnOrder": 10, "ReorderLevel": 15, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 69, "ProductName": "Gudbrandsdalsost", "SupplierID": 15, "CategoryID": 4, "QuantityPerUnit": "10 kg pkg.", "UnitPrice": 36.0000, "UnitsInStock": 26, "UnitsOnOrder": 0, "ReorderLevel": 15, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 70, "ProductName": "Outback Lager", "SupplierID": 7, "CategoryID": 1, "QuantityPerUnit": "24 - 355 ml bottles", "UnitPrice": 15.0000, "UnitsInStock": 15, "UnitsOnOrder": 10, "ReorderLevel": 30, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 71, "ProductName": "Flotemysost", "SupplierID": 15, "CategoryID": 4, "QuantityPerUnit": "10 - 500 g pkgs.", "UnitPrice": 21.5000, "UnitsInStock": 26, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 72, "ProductName": "Mozzarella di Giovanni", "SupplierID": 14, "CategoryID": 4, "QuantityPerUnit": "24 - 200 g pkgs.", "UnitPrice": 34.8000, "UnitsInStock": 14, "UnitsOnOrder": 0, "ReorderLevel": 0, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 73, "ProductName": "R\u00f6d Kaviar", "SupplierID": 17, "CategoryID": 8, "QuantityPerUnit": "24 - 150 g jars", "UnitPrice": 15.0000, "UnitsInStock": 101, "UnitsOnOrder": 0, "ReorderLevel": 5, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 74, "ProductName": "Longlife Tofu", "SupplierID": 4, "CategoryID": 7, "QuantityPerUnit": "5 kg pkg.", "UnitPrice": 10.0000, "UnitsInStock": 4, "UnitsOnOrder": 20, "ReorderLevel": 5, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 75, "ProductName": "Rh\u00f6nbr\u00e4u Klosterbier", "SupplierID": 12, "CategoryID": 1, "QuantityPerUnit": "24 - 0.5 l bottles", "UnitPrice": 7.7500, "UnitsInStock": 125, "UnitsOnOrder": 0, "ReorderLevel": 25, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 76, "ProductName": "Lakkalik\u00f6\u00f6ri", "SupplierID": 23, "CategoryID": 1, "QuantityPerUnit": "500 ml", "UnitPrice": 18.0000, "UnitsInStock": 57, "UnitsOnOrder": 0, "ReorderLevel": 20, "Discontinued": false }));
this.push(new NwindDataItem({ "ProductID": 77, "ProductName": "Original Frankfurter gr\u00fcne So\u00dfe", "SupplierID": 12, "CategoryID": 2, "QuantityPerUnit": "12 boxes", "UnitPrice": 13.0000, "UnitsInStock": 32, "UnitsOnOrder": 0, "ReorderLevel": 15, "Discontinued": false }));
}
}
tsimport { IgcForOfState } from "igniteui-webcomponents-grids/grids";
import { NwindData, NwindDataItem } from "./NwindData";
import { BehaviorSubject, Observable } from 'rxjs';
const DATA_URL: string = 'https://services.odata.org/V4/Northwind/Northwind.svc/Products';
export class RemoteNwindService {
// public remoteData: NwindDataItem[];
// constructor() {
// this.remoteData = new NwindData();
// }
// public getData(index?: number, perPage?: number): Promise<NwindDataItem[]> {
// const data = this.remoteData.slice(index * perPage, index * perPage + perPage);
// return new Promise((resolve, reject) => {
// setTimeout(resolve, 500, data);
// });
// }
// public getDataLength(): Promise<number> {
// return Promise.resolve(this.remoteData.length);
// }`
public data: Observable<any[]>;
private _data: BehaviorSubject<any[]>;
private _cachedData = <any>[];
private _prevRequestChunk: number;
constructor() {
this._data = new BehaviorSubject([]);
this.data = this._data.asObservable();
}
public get cachedData() {
return this._cachedData;
}
public async loadDataForPage(page: number, pageSize: number, callback?: (arg: any) => void) {
const url = this._buildDataUrl(page, pageSize)
const response = await fetch(url);
const data = await response.json();
const startIndex = (page - 1) * pageSize;
this._updateData(data, startIndex);
this._data.next(data);
callback({ data });
}
public getCachedData(virtualizationArgs: IgcForOfState) {
const virtArgsEndIndex = virtualizationArgs.startIndex + virtualizationArgs.chunkSize;
let data = [];
if (virtArgsEndIndex > this._cachedData.length) {
data = this._cachedData.slice(this._cachedData.length - this._prevRequestChunk + 1);
} else {
data = this._cachedData.slice(virtualizationArgs.startIndex, virtArgsEndIndex);
this._prevRequestChunk = virtualizationArgs.chunkSize;
}
return data;
}
private _updateData(data: any, startIndex: number) {
for (let i = 0; i < data.value.length; i++) {
this._cachedData[i + startIndex] = data.value[i];
}
}
private _buildDataUrl(page: number, pageSize: number): string {
let baseQueryString = `${DATA_URL}?$count=true&`;
const skip = (page - 1) * pageSize;
const pageQuery = `$skip=${skip}&$top=${pageSize}`;
baseQueryString += pageQuery;
return baseQueryString;
}
}
tsimport { IgcPropertyEditorPanelModule } from 'igniteui-webcomponents-layouts';
import 'igniteui-webcomponents-grids/grids/combined';
import { ComponentRenderer, PropertyEditorPanelDescriptionModule, WebGridDescriptionModule } from 'igniteui-webcomponents-core';
import { IgcGridComponent, IgcColumnComponent, IgcForOfState } from 'igniteui-webcomponents-grids/grids';
import { NwindDataItem, NwindDataItem_LocationsItem, NwindData } from './NwindData';
import "igniteui-webcomponents-grids/grids/themes/light/bootstrap.css";
import { ModuleManager } from 'igniteui-webcomponents-core';
import { RemoteNwindService } from './NwindService';
ModuleManager.register(
IgcPropertyEditorPanelModule
);
export class Sample {
private grid: IgcGridComponent;
public remoteData: any;
private page = 1;
private pageSize = 10;
private totalPageCount = 0;
private totalItems = 0;
private iD: IgcColumnComponent
private productName: IgcColumnComponent
private quantityPerUnit: IgcColumnComponent
private unitPrice: IgcColumnComponent
private orderDate: IgcColumnComponent
private discontinued: IgcColumnComponent
private _bind: () => void;
private remoteService = new RemoteNwindService();
constructor() {
var grid = this.grid = document.getElementById('grid') as IgcGridComponent;
var iD = this.iD = document.getElementById('ID') as IgcColumnComponent;
var productName = this.productName = document.getElementById('ProductName') as IgcColumnComponent;
var quantityPerUnit = this.quantityPerUnit = document.getElementById('QuantityPerUnit') as IgcColumnComponent;
var unitPrice = this.unitPrice = document.getElementById('UnitPrice') as IgcColumnComponent;
var orderDate = this.orderDate = document.getElementById('OrderDate') as IgcColumnComponent;
var discontinued = this.discontinued = document.getElementById('Discontinued') as IgcColumnComponent;
this.grid.isLoading = true;
// load 1 page of data with the size of a data view and a half
const dataViewSize = 9.6; // grid.height / grid.rowHeight;
this.pageSize = Math.floor(dataViewSize * 1.5);
this.remoteService.loadDataForPage(this.page, this.pageSize, (request) => {
if (request.data) {
this.grid.data = this.remoteService.getCachedData({ startIndex: 0, chunkSize: 10 });
this.grid.totalItemCount = this.page * this.pageSize;
this.totalItems = request.data['@odata.count'];
this.totalPageCount = Math.ceil(this.totalItems / this.pageSize);
this.grid.isLoading = false;
}
});
this._bind = () => {
this.grid.addEventListener('dataPreLoad', (e) => {
this.handlePreLoad(e as CustomEvent<IgcForOfState>);
});
}
this._bind();
}
private _nwindData: NwindData = null;
public get nwindData(): NwindData {
if (this._nwindData == null) {
this._nwindData = new NwindData();
}
return this._nwindData;
}
public handlePreLoad(e: CustomEvent<IgcForOfState>) {
const isLastChunk = this.grid.totalItemCount === e.detail.startIndex + e.detail.chunkSize;
// when last chunk reached load another page of data
if (isLastChunk) {
if (this.totalPageCount === this.page) {
this.grid.data = this.remoteService.getCachedData(e.detail);
return;
}
this.page++;
this.grid.isLoading = true;
this.remoteService.loadDataForPage(this.page, this.pageSize, (request) => {
if (request.data) {
this.grid.totalItemCount = Math.min(this.page * this.pageSize, this.totalItems);
this.grid.data = this.remoteService.getCachedData(e.detail);
this.grid.isLoading = false;
}
});
} else {
this.grid.data = this.remoteService.getCachedData(e.detail);
}
}
}
new Sample();
ts<!DOCTYPE html>
<html>
<head>
<title>Sample | Ignite UI | Web Components | infragistics</title>
<meta charset="UTF-8" />
<link rel="shortcut icon" href="https://static.infragistics.com/xplatform/images/browsers/wc.png" >
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Kanit&display=swap" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium Web" />
<link rel="stylesheet" href="https://static.infragistics.com/xplatform/css/samples/shared.v8.css" />
<link rel="stylesheet" href="/src/index.css" type="text/css" />
</head>
<body>
<div id="root">
<div class="container sample">
<div class="container fill">
<igc-grid id="grid" name="grid" height="480px" width="100%" autoGenerate='false'>
<igc-column field="ProductID"></igc-column>
<igc-column field="ProductName"></igc-column>
<igc-column field="UnitPrice" data-type="number"></igc-column>
<igc-column field="UnitsInStock" data-type="number" header-classes="headerAlignSyle">
<!-- <ng-template igcHeader>
<span class="cellAlignSyle">UnitsInStock</span>
</ng-template>
<ng-template igcCell let-val>
<div class="currency-badge-container">
<igc-badge *ngIf="val>50" type="success" position="bottom-right" icon="arrow_upward" class="badge-left"></igc-badge>
<igc-badge *ngIf="val<=50" type="error" position="bottom-right" icon="arrow_downward" class="error badge-left"></igc-badge>
<span class="cellAlignSyle" [class.up]="val>50" [class.down]="val<=50">{{ formatNumber(val) }}</span>
</div>
</ng-template> -->
</igc-column>
<igc-column field="QuantityPerUnit"></igc-column>
<igc-column field="ReorderLevel" data-type="number" header-classes="headerAlignSyle">
<!-- <ng-template igcHeader>
<span class="cellAlignSyle">ReorderLevel</span>
</ng-template>
<ng-template igcCell let-val>
<div class="currency-badge-container">
<igc-badge *ngIf="val>20" type="success" position="bottom-right" icon="arrow_upward" class="badge-left"></igc-badge>
<igc-badge *ngIf="val<=20" type="error" position="bottom-right" icon="arrow_downward" class="error badge-left"></igc-badge>
<span class="cellAlignSyle" [class.up]="val>0" [class.down]="val<=0">{{ formatNumber(val) }}</span>
</div>
</ng-template> -->
</igc-column>
</igc-grid>
</div>
</div>
</div>
<!-- This script is needed only for parcel and it will be excluded for webpack -->
<% if (false) { %><script src="src/index.ts"></script><% } %>
</body>
</html>
html/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
css
Like this sample? Get access to our complete Ignite UI for Web Components toolkit and start building your own apps in minutes. Download it for free.
Remote Paging
페이징 기능은 원격 데이터로 작동할 수 있습니다. 이를 시연하기 위해 먼저 데이터 가져오기를 담당할 서비스를 선언하겠습니다. 페이지 수를 계산하려면 모든 데이터 항목의 수가 필요합니다. 이 로직은 우리 서비스에 추가될 예정입니다.
export class RemotePagingService {
public static CUSTOMERS_URL = `https://data-northwind.indigo.design/Customers/GetCustomersWithPage`;
constructor() {}
public static getDataWithPaging(pageIndex?: number, pageSize?: number) {
return fetch(RemotePagingService.buildUrl(RemotePagingService.CUSTOMERS_URL, pageIndex, pageSize))
.then((result) => result.json())
.catch((error) => console.error(error.message));
}
private static buildUrl(baseUrl: string, pageIndex?: number, pageSize?: number) {
let qS = "";
if (baseUrl) {
qS += `${baseUrl}`;
}
// Add pageIndex and size to the query string if they are defined
if (pageIndex !== undefined) {
qS += `?pageIndex=${pageIndex}`;
if (pageSize !== undefined) {
qS += `&size=${pageSize}`;
}
} else if (pageSize !== undefined) {
qS += `?perPage=${pageSize}`;
}
return `${qS}`;
}
}
ts
서비스를 선언한 후 구성 및 데이터 구독을 담당 IgcGridComponent
할 구성 요소를 만들어야 합니다.
먼저 페이지와 페이지당 표시되는 레코드의 양을 변경할 때 원격 서비스가 올바른 양의 데이터를 가져올 수 있도록 관련 이벤트에 바인딩해야 합니다
constructor() {
this.grid = document.getElementById('grid') as IgcGridComponent;
this.pager = document.getElementById('paginator') as IgcPaginatorComponent;
this._bind = () => {
window.addEventListener("load", () => {
this.loadData(this.page,this.perPage);
});
this.pager.addEventListener("perPageChange", ((args: CustomEvent<any>) => {
this.perPage = args.detail;
this.loadData(this.page, this.perPage);
}) as EventListener);
this.pager.addEventListener("pageChange", ((args: CustomEvent<any>) => {
this.page = args.detail;
this.loadData(this.page, this.perPage);
}) as EventListener);
}
this._bind();
}
ts
또한 데이터를 로드하는 방법을 설정하고 그에 따라 UI를 업데이트해야 합니다.
private loadData(pageIndex?: number, pageSize?: number): void {
this.grid.isLoading = true;
RemotePagingService.getDataWithPaging(pageIndex,pageSize)
.then((response: CustomersWithPageResponseModel) => {
this.totalRecordsCount = response.totalRecordsCount;
this.pager.perPage = pageSize;
this.pager.totalRecords = this.totalRecordsCount;
this.page = response.pageNumber;
this.data = response.items;
this.grid.isLoading = false;
this.updateUI(); // Update the UI after receiving data
})
.catch((error) => {
console.error(error.message);
// Stop loading even if error occurs. Prevents endless loading
this.grid.isLoading = false;
this.updateUI();
})
}
private updateUI(): void {
if (this.grid && this.data) { // Check if grid and data are available
this.grid.data = this.data;
}
}
ts
자세한 내용은 아래 데모를 확인하십시오.
Grid Remote Paging Demo
export interface CustomersWithPageResponseModel {
items: any[];
totalRecordsCount: number;
pageSize: number;
pageNumber: number;
totalPages: number;
}
tsexport class RemotePagingService {
public static CUSTOMERS_URL = `https://data-northwind.indigo.design/Customers/GetCustomersWithPage`;
constructor() {}
public static getDataWithPaging(pageIndex?: number, pageSize?: number) {
return fetch(RemotePagingService.buildUrl(RemotePagingService.CUSTOMERS_URL, pageIndex, pageSize))
.then((result) => result.json())
.catch((error) => console.error(error.message));
}
private static buildUrl(baseUrl: string, pageIndex?: number, pageSize?: number) {
let qS = "";
if (baseUrl) {
qS += `${baseUrl}`;
}
// Add pageIndex and size to the query string if they are defined
if (pageIndex !== undefined) {
qS += `?pageIndex=${pageIndex}`;
if (pageSize !== undefined) {
qS += `&size=${pageSize}`;
}
} else if (pageSize !== undefined) {
qS += `?perPage=${pageSize}`;
}
return `${qS}`;
}
}
tsimport 'igniteui-webcomponents-grids/grids/combined';
import { IgcGridComponent, IgcPaginatorComponent } from 'igniteui-webcomponents-grids/grids';
import "igniteui-webcomponents-grids/grids/themes/light/bootstrap.css";
import "./index.css";
import { RemotePagingService } from './RemotePagingService';
import { CustomersWithPageResponseModel } from './CustomersWithPageResponseModel';
export class Sample {
public data: any[] = [];
public page: number = 0;
private grid: IgcGridComponent;
private _bind: () => void;
private _perPage: number = 15;
private pager: IgcPaginatorComponent;
private _totalRecordsCount: number;
public get perPage(): number {
return this.pager.perPage || this._perPage;
}
public set perPage(val: number) {
this._perPage = val;
}
public get totalRecordsCount(): number {
return this._totalRecordsCount;
}
public set totalRecordsCount(value: number) {
this._totalRecordsCount = value;
this.grid.totalRecords = value;
}
constructor() {
this.grid = document.getElementById('grid') as IgcGridComponent;
this.pager = document.getElementById('paginator') as IgcPaginatorComponent;
this._bind = () => {
window.addEventListener("load", () => {
this.loadData(this.page,this.perPage);
});
this.pager.addEventListener("perPageChange", ((args: CustomEvent<any>) => {
this.perPage = args.detail;
this.loadData(this.page, this.perPage);
}) as EventListener);
this.pager.addEventListener("pageChange", ((args: CustomEvent<any>) => {
this.page = args.detail;
this.loadData(this.page, this.perPage);
}) as EventListener);
}
this._bind();
}
private updateUI(): void {
if (this.grid && this.data) { // Check if grid and data are available
this.grid.data = this.data;
}
}
private loadData(pageIndex?: number, pageSize?: number): void {
this.grid.isLoading = true;
RemotePagingService.getDataWithPaging(pageIndex,pageSize)
.then((response: CustomersWithPageResponseModel) => {
this.totalRecordsCount = response.totalRecordsCount;
this.pager.perPage = pageSize;
this.pager.totalRecords = this.totalRecordsCount;
this.page = response.pageNumber;
this.data = response.items;
this.grid.isLoading = false;
this.updateUI(); // Update the UI after receiving data
})
.catch((error) => {
console.error(error.message);
// Stop loading even if error occurs. Prevents endless loading
this.grid.isLoading = false;
this.updateUI();
})
}
}
new Sample();
ts<!DOCTYPE html>
<html>
<head>
<title>Sample | Ignite UI | Web Components | infragistics</title>
<meta charset="UTF-8" />
<link rel="shortcut icon" href="https://static.infragistics.com/xplatform/images/browsers/wc.png" >
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Kanit&display=swap" />
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Titillium Web" />
<link rel="stylesheet" href="https://static.infragistics.com/xplatform/css/samples/shared.v8.css" />
<link rel="stylesheet" href="/src/index.css" type="text/css" />
</head>
<body>
<div id="root">
<div class="container sample ig-typography">
<div class="container fill">
<igc-grid
auto-generate="false"
name="grid"
id="grid"
moving="true"
paging-mode="Remote">
<igc-paginator
id="paginator">
</igc-paginator>
<igc-column
name="customerId"
id="customerId"
field="customerId"
hidden="true">
</igc-column>
<igc-column
name="companyName"
id="companyName"
field="companyName"
header="Company Name">
</igc-column>
<igc-column
name="contactName"
id="contactName"
field="contactName"
header="Contact Name">
</igc-column>
<igc-column
name="contactTitle"
id="contactTitle"
field="contactTitle"
header="Contact Title">
</igc-column>
<igc-column
name="address?.country"
id="address.country"
field="address.country"
header="Country">
</igc-column>
<igc-column
name="address.phone"
id="address.phone"
field="address.phone"
header="Phone">
</igc-column>
</igc-grid>
</div>
</div>
</div>
<!-- This script is needed only for parcel and it will be excluded for webpack -->
<% if (false) { %><script src="src/index.ts"></script><% } %>
</body>
</html>
html/* shared styles are loaded from: */
/* https://static.infragistics.com/xplatform/css/samples */
css
Known Issues and Limitations
- 그리드에
PrimaryKey
설정되어 있지 않고 원격 데이터 시나리오가 활성화된 경우(그리드에 표시할 데이터를 검색하기 위해 원격 서버에 대한 페이징, 정렬, 필터링, 스크롤 트리거 요청 시) 행은 데이터 이후 다음 상태를 잃게 됩니다. 요청이 완료되었습니다:
- 행 선택
- 행 확장/축소
- 행 편집
- 행 고정
API References
Additional Resources
우리 커뮤니티는 활동적이며 항상 새로운 아이디어를 환영합니다.