마스터-상세

FlexGrid와 DetailView

계층 데이터를 처리하는 가장 간단한 방법은 마스터 상세 모델을 사용하는 것 입니다. 메인 항목을 선택하고 메인 항목의 세부 사항을 표시하기 위한 하나 이상의 추가 컨트롤을 사용합니다.

아래 예제에서는 FlexGrid가 마스터 컨트롤로 사용됩니다. 그리드에서 항목을 선택하고 컨트롤에서 세부 사항을 참고하시기 바랍니다.

// create some random data
var countries = 'US,Germany,UK,Japan,Italy,Greece'.split(',');
var products = 'Phones,Cars,Stereos,Watches,Computers'.split(',');
var data = [];
for (var i = 0; i < 50; i++) {
data.push({
id: i,
country: countries[i % countries.length],
product: products[i % products.length],
date: wijmo.DateTime.addDays(new Date(), i),
sales: Math.random() * 10000,
expenses: Math.random() * 5000,
});
}
// using a grid as the master
var theGridMaster = new wijmo.grid.FlexGrid('#theGridMaster', {
itemsSource: data,
selectionMode: 'Row',
isReadOnly: true,
selectionChanged: function(s, e) {
updateDetailControls();
}
});
// update detail controls when selection changes
function updateDetailControls() {
var item = theGridMaster.collectionView.currentItem;
var bndCtls = document.querySelectorAll('.bnd-ctl');
for (var i = 0; i < bndCtls.length; i++) {
var host = bndCtls[i];
var prop = host.id.substr(3).toLowerCase();
var ctl = wijmo.Control.getControl(host);
if (wijmo.isString(item[prop])) {
ctl.text = item[prop];
} else {
ctl.value = item[prop];
}
}
}
// set a property on the current item
function setProperty(prop, val) {
var v = theGridMaster.collectionView;
v.editItem(v.currentItem);
v.currentItem[prop] = val;
v.commitEdit();
}
// define detail controls
var theCountry = new wijmo.input.ComboBox('#theCountry', {
itemsSource: countries,
textChanged: function(s, e) {
setProperty('country', s.text);
}
});
var theProduct = new wijmo.input.ComboBox('#theProduct', {
itemsSource: products,
textChanged: function(s, e) {
setProperty('product', s.text);
}
});
var theDate = new wijmo.input.InputDate('#theDate', {
valueChanged: function(s, e) {
setProperty('date', s.value);
}
});
var theSales = new wijmo.input.InputNumber('#theSales', {
format: 'n2',
step: 10,
valueChanged: function(s, e) {
setProperty('sales', s.value);
}
});
var theExpenses = new wijmo.input.InputNumber('#theExpenses', {
format: 'n2',
step: 10,
valueChanged: function(s, e) {
setProperty('expenses', s.value);
}
});

RowDetails를 사용한 중첩된 FlexGrid

때로는 행이 일반 그리드에 쉽게 적용될 수 있는 것보다 더 많은 정보를 포함하는 데이터 객체에 바인딩되기도 합니다.

이러한 경우에는 wijmo.grid.detail 모듈에 포함된 FlexGridDetailProvider 클래스를 사용할 수 있습니다.

FlexGridDetailProvider는 행 헤더에 축소/확장 버튼을 추가하고 항목에 대한 추가 세부 정보를 제공하는 데 사용할 수 있는 createDetailCell 메서드를 추가하여 FlexGrid를 확장합니다. 세부 정보가 확장되면 그리드에 추가된 '세부 정보 행'에 표시되고 축소되면 제거됩니다.

다른 그리드를 포함하여 상세 행에 원하는 모든 항목을 추가할 수 있습니다. 아래 예에서는 동일한 카테고리를 표시하지만 세부 사항 행은 다른 그리드를 사용하여 제품을 표시합니다.

import * as wjOdata from '@grapecity/wijmo.odata';
import * as wjGrid from '@grapecity/wijmo.grid';
import * as wjGridDetail from '@grapecity/wijmo.grid.detail';
// get OData categories and products
var url = 'https://services.odata.org/Northwind/Northwind.svc';
var categories = new wjOdata.ODataCollectionView(url, 'Categories', {
fields: ['CategoryID', 'CategoryName', 'Description']
})
var products = new wjOdata.ODataCollectionView(url, 'Products');
// shared column definitions
var categoryColumns = [{
binding: 'CategoryName',
header: 'Category Name',
width: '*'
},
{
binding: 'Description',
header: 'Description',
width: '2*'
}
];
// get products for a given category
function getProducts(categoryID) {
var arr = [];
products.items.forEach(function(product) {
if (product.CategoryID == categoryID) {
arr.push(product);
}
});
return arr;
}
// grid with grid detail
var gridDetail = new wjGrid.FlexGrid('#gridDetail', {
autoGenerateColumns: false,
columns: categoryColumns,
itemsSource: categories,
isReadOnly: true
});
// grid detail provider
var dpGrid = new wjGridDetail.FlexGridDetailProvider(gridDetail, {
// use animation when showing details
isAnimated: true,
// limit height of detail rows
maxHeight: 150,
// create detail cells for a given row
createDetailCell: function(row) {
var cell = document.createElement('div');
var detailGrid = new wjGrid.FlexGrid(cell, {
headersVisibility: wjGrid.HeadersVisibility.Column,
isReadOnly: true,
autoGenerateColumns: false,
itemsSource: getProducts(row.dataItem.CategoryID),
columns: [{
header: 'ID',
binding: 'ProductID'
},
{
header: 'Name',
binding: 'ProductName'
},
{
header: 'Qty/Unit',
binding: 'QuantityPerUnit'
},
{
header: 'Unit Price',
binding: 'UnitPrice'
},
{
header: 'Discontinued',
binding: 'Discontinued'
}
]
});
return cell;
}
});