Blazor Grid 개요 및 구성
Blazor Data Grid Example
이 Ignite UI for Blazor Grid 예제에서는 사용자가 기본 및 Excel 스타일 필터링, 라이브 데이터 정렬, 그리드 요약 및 셀 템플릿을 사용하는 방법을 확인할 수 있습니다. 데모에는 페이지당 10개 항목을 표시하도록 설정된 페이징도 포함됩니다.
Getting Started with Blazor Data Grid
Dependencies
To get started with the Blazor Data Grid, first you need to install the IgniteUI.Blazor package.
IgniteUI.Blazor 패키지 추가에 대한 다음 항목을 참조하십시오.
또한 그리드에 필요한 스타일을 제공하려면 애플리케이션의 index.html 파일에 다음 CSS 링크를 포함해야 합니다.
<link href="_content/IgniteUI.Blazor/themes/grid/light/bootstrap.css" rel="stylesheet" />
그런 다음 다음 네임스페이스를 추가하여 컨트롤 구현을 시작할 수 있습니다.
@using IgniteUI.Blazor.Controls
Component Modules
The DataGrid requires the following modules:
// in Program.cs file
builder.Services.AddIgniteUIBlazor(typeof(IgbGridModule));
Usage
이제 그리드 패키지를 가져왔으므로 기본 구성을 시작하고 로컬 데이터에 바인딩하겠습니다.
<IgbGrid Id="grid1" Data="data" AutoGenerate="true"></IgbGrid>
The Id property is a string value and is the unique identifier of the grid which will be auto-generated if not provided, while data binds the grid, in this case to local data.
The AutoGenerate property tells the grid to auto generate the grid's IgbColumn components based on the data source fields. It will also try to deduce the appropriate data type for the column if possible. Otherwise, the developer needs to explicitly define the columns and the mapping to the data source fields.
Editable Blazor Grid
그리드 편집을 위한 각 작업에는 일괄 작업이 포함되어 있습니다. 즉, API는 편집 내용을 단일 서버 호출로 그룹화하거나 그리드 상호 작용으로 발생하는 대로 그리드 편집/업데이트 작업을 수행할 수 있는 옵션을 제공합니다. CRUD 작업이 있는 편집 가능한 그리드로서 훌륭한 개발자 경험과 함께 그리드에는 Excel과 같은 키보드 탐색이 포함됩니다. 일반적인 기본 그리드 탐색이 포함되어 있으며, 고객의 요구 사항을 충족시키기 위해 모든 탐색 옵션을 재정의하는 옵션도 있습니다. 훌륭한 탐색 체계가 있는 편집 가능한 그리드는 모든 최신 사업 분야 애플리케이션에 필수적이며, Ignite UI 그리드를 사용하면 쉽게 만들 수 있습니다.
이 주제를 따라 셀 템플릿 및 셀 편집 템플릿과 편집에 대해 자세히 알아봅니다.
Grid Column Configuration
IgbColumn is used to define the grid's columns collection and to enable features per column like sorting and filtering. Cell, header, and footer templates are also available.
Defining Columns
Let's turn the AutoGenerate property off and define the columns collection in the markup:
<IgbGrid AutoGenerate=false AllowFiltering=true>
<IgbColumn Field="Name" Sortable=true />
<IgbColumn Field="AthleteNumber" Sortable=true Header="Athlete Number" Filterable=false/>
<IgbColumn Field="TrackProgress" Header="Track Progress" Filterable=false />
</IgbGrid>
Header Template
열 머리글을 수정하도록 머리글 템플릿을 설정할 수 있습니다. 아래 스니펫은 헤더 텍스트를 대문자로 포맷하는 방법을 보여줍니다.
<IgbColumn Field="Name" HeaderTemplateScript="UpperCaseTemplate" />
//In JavaScript:
igRegisterScript("UpperCaseTemplate", (ctx) => {
var html = window.igTemplating.html;
return html`${this.formatUppercase(ctx.column.field)}`;
}, false)
function formatUppercase(value) {
return value.toUpperCase();
}
Cell Template
셀 템플릿이 설정되면 열의 모든 셀이 변경됩니다. 템플릿에서 제공되는 컨텍스트 개체는 암시적으로 제공된 셀 값과 셀 개체 자체로 구성됩니다. 예를 들어 제목 케이스와 같이 셀의 텍스트가 형식화될 수 있는 템플릿을 정의하는 데 사용할 수 있습니다.
<IgbColumn Field="Name" BodyTemplateScript="NameCellTemplate"/>
//In JavaScript:
igRegisterScript("NameCellTemplate", (ctx) => {
var html = window.igTemplating.html;
return html`${this.formatTitleCase(ctx.implicit)}`;
}, false);
function formatTitleCase(value) {
return value.toUpperCase();
}
In the snippet above we take a reference to the implicitly provided cell value. This is sufficient if you just want to present some data and maybe apply some custom styling or pipe transforms over the value of the cell. However even more useful is to take the Cell instance itself as shown below:
<IgbGrid Id="grid" AutoGenerate=false>
<IgbColumn Field="Name" BodyTemplateScript="NameCellTemplate" />
<IgbColumn Field="Subscription" BodyTemplateScript="SubscriptionCellTemplate" />
</IgbGrid>
//In JavaScript:
igRegisterScript("NameCellTemplate", (ctx) => {
var html = window.igTemplating.html;
return html`
<span tabindex="0" @keyup=${(e) => this.deleteRow(e, ctx.cell.id.rowIndex)}> ${this.formatTitleCase(ctx.cell.value)}</span >
`;
}, false);
igRegisterScript("SubscriptionCellTemplate", (ctx) => {
var html = window.igTemplating.html;
if (ctx.cell.value) {
return html` <input type="checkbox" checked /> `;
} else {
return html` <input type="checkbox"/> `;
}
}, false);
function deleteRow(e, rowIndex) {
if (e.code === "Delete") {
this.grid.deleteRow(rowIndex);
}
}
function formatTitleCase(value) {
return value.toUpperCase();
}
Note: The grid exposes a default handling for number, string, date and boolean column types. For example, the column will display
checkorcloseicon, instead of true/false by default, for boolean column type.
When properly implemented, the cell editing template also ensures that the cell's EditValue will correctly pass through the grid editing event cycle.
Cell Editing Template
The column also accepts one last template that will be used when a cell is in edit mode. As with the other column templates, the provided context object is again the cell value and the cell object itself. Of course in order to make the edit-mode template accessible to end users, you need
to set the Editable property of the column to true.
<IgbColumn Field="Price" Editable=true DataType="GridColumnDataType.Number" InlineEditorTemplateScript="PriceCellTemplate" />
//In JavaScript:
igRegisterScript("PriceCellTemplate", (ctx) => {
var html = window.igTemplating.html;
return html`
<label>
Enter the new price tag
</label>
<input name="price" type="number" value="${ctx.cell.value}"
@change=${(e) => this.updateValue(e, ctx.cell.value)} />
`;
}, false);
function updateValue(event, value) {
}
Make sure to check the API for the Cell in order to get accustomed with the provided properties you can use in your templates.
Column Template API
Each of the column templates can be changed programmatically at any point through the IgbColumn object itself. For example in the code below, we have declared two templates for our user data. In our TypeScript code we'll get references to the templates themselves and then based on some condition we will render the appropriate template for the column in our application.
<IgbGrid ColumnInit=OnColumnInit />
@code {
public void OnColumnInit(IgbColumnComponentEventArgs args)
{
IgbColumn column = args.Detail;
// Return the appropriate template based on some condition.
// For example saved user settings, viewport size, etc.
column.BodyTemplateScript = "NormalViewTemplate";
}
}
//In JavaScript:
igRegisterScript("NormalViewTemplate", (ctx) => {
var html = window.igTemplating.html;
return html`
<div class="user-details">${ctx.cell.value}</div>
<user-details-component></user-details-component>
`;
}, false);
igRegisterScript("SmallViewTemplate", (ctx) => {
var html = window.igTemplating.html;
return html`
<div class="user-details-small" style="color: blue">${ctx.cell.value}</div>
`;
}, false);
Column properties can also be set in code in the ColumnInit event which is emitted when the columns are initialized in the grid.
<IgbGrid ColumnInit=OnColumnInit />
@code {
public void OnColumnInit(IgbColumnComponentEventArgs args)
{
IgbColumn column = args.Detail;
if (column.Field == "ProductName") {
column.Sortable = true;
column.Editable = true;
}
}
}
위의 코드는 ProductName 열을 정렬 및 편집 가능하게 만들고 해당 기능 UI(편집을 위한 입력 등)를 인스턴스화합니다.
Custom Display Format
형식화를 위한 선택적 매개변수가 있습니다.
Format- determines what date/time parts are displayed, defaults to'mediumDate', equivalent to 'MMM d, y'Timezone- the timezone offset for dates. By default uses the end-user's local system timezoneDigitsInfo- decimal representation objects. Default to 1.0-3
To allow customizing the display format by these parameters, the PipeArgs input is exposed. A column will respect only the corresponding properties for its data type, if PipeArgs is set. Example:
<IgbColumn Field="OrderDate"
DataType=GridColumnDataType.Date
PipeArgs=@(new IgbColumnPipeArgs() { Timezone="UTC+0", DigitsInfo="1.2-2", Format = "longDate" }) />
<IgbColumn Field="UnitPrice"
DataType=GridColumnDataType.Date
PipeArgs=@(new IgbColumnPipeArgs() { Timezone="UTC+0", DigitsInfo="1.2-2", Format = "longDate" }) />
The OrderDate column will respect only the Format and Timezone properties, while the UnitPrice will only respect the DigitsInfo.
사용 가능한 모든 열 데이터 유형은 공식 열 유형 항목에서 찾을 수 있습니다.
Complex Data Binding
복잡한 데이터 바인딩을 사용하면 다단계 데이터, 복잡한 실제 데이터 세트, 객체 지향 데이터 모듈 등과 원활하게 상호 작용할 수 있습니다. Blazor Data Grid를 사용하면 복잡한 개체(한 수준보다 더 깊게 중첩되는 데이터 구조 포함)에 쉽게 바인딩할 수 있습니다. 이는 데이터 레코드의 속성 경로를 통해 발생합니다.
다음 데이터 모델을 살펴보십시오.
public class AminoAcid
{
public string Name { get; set; }
public AminoAbbreviation Abbreviation { get; set; }
public AminoWeight Weight { get; set; }
}
public class AminoAbbreviation
{
public string Short { get; set; }
public string Long { get; set; }
}
public class AminoWeight
{
public double Molecular { get; set; }
public double Residue { get; set; }
}
예를 들어 그리드에 주어진 아미노산의 가중치를 표시하려면 다음 스니펫으로 충분합니다.
<IgbColumn Field="Weight.Molecular" />
<IgbColumn Field="Weight.Residue" />
An alternative way to bind complex data, or to visualize composite data (from more than one column) in the IgbGrid is to use a custom body template for the column. Generally, one can:
- use the
valueof the cell, that contains the nested data
<IgbColumn Field="Abbreviation.Long" BodyTemplateScript="AbbreviationLongCellTemplate"/>
//In JavaScript:
igRegisterScript("AbbreviationLongCellTemplate", (ctx) => {
var html = window.igTemplating.html;
return html`
<div>
<div>
${ctx.cell.value}
${this.GetName(ctx.cell.id.rowIndex)}
${this.GetWeight(ctx.cell.id.rowIndex)}
</div>
</div>
`;
}, false);
function GetName(rowIndex) {
return this.grid.getRowByIndex(rowIndex).data["Name"];
}
function GetWeight(rowIndex) {
return this.grid.getRowByIndex(rowIndex).data["Weight"]["Molecular"];
}
다음은 본문 템플릿을 사용하여 복잡한 데이터를 표시하는 방법에 대한 예입니다. 다음은 우리가 사용할 데이터입니다.
public class EmployeesNestedData : List<EmployeesNestedDataItem>
{
public EmployeesNestedData()
{
this.Add(new EmployeesNestedDataItem()
{
Age = 55,
Employees = new List<EmployeesNestedDataItem_EmployeesItem>()
{
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 43,
Salary = 70000,
Productivity = 80,
City = @"Hamburg",
Country = @"Germany",
Phone = @"609-444-555",
HireDate = @"2011, 6, 3",
ID = 3,
Name = @"Michael Burke",
Title = @"Senior Software Developer"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 29,
Salary = 60000,
Productivity = 80,
City = @"Munich",
Country = @"Germany",
Phone = @"609-333-444",
HireDate = @"2009, 6, 19",
ID = 2,
Name = @"Thomas Anderson",
Title = @"Senior Software Developer"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 31,
Salary = 90000,
Productivity = 80,
City = @"Warasw",
Country = @"Poland",
Phone = @"609-222-205",
HireDate = @"2014, 8, 18",
ID = 11,
Name = @"Monica Reyes",
Title = @"Software Development Team Lead"
},
new EmployeesNestedDataItem_EmployeesItem()
{
Age = 35,
Salary = 70000,
Productivity = 70,
City = @"Koln",
Country = @"Germany",
Phone = @"609-502-525",
HireDate = @"2015, 9, 17",
ID = 6,
Name = @"Roland Mendel",
Title = @"Senior Software Developer"
}}
});
}
}
}
중첩 데이터를 렌더링할 열의 사용자 지정 템플릿:
<IgbColumn Header="Employees" Field="Employees" BodyTemplateScript="WebGridNestedDataCellTemplate" />
//In JavaScript:
igRegisterScript("WebGridNestedDataCellTemplate", (ctx) => {
var html = window.igTemplating.html;
window.keyUpHandler = function() {
ctx.cell.row.data[window.event.target.id] = window.event.target.value;
}
const people = ctx.cell.value;
if (people != null) {
if (people.length === 0) return html``;
const person = people[0];
return html`
<igc-expansion-panel>
<h3 slot="title">
${person.Name}
</h3>
<div class="description">
<div>
<label for="title">Title</label>
<input id='Title' type="text" name="title" value="${person.Title}" style="text-overflow: ellipsis;" />
</div>
<div>
<label for="age">Age</label>
<input id='Age' type="text" name="title" value="${person.Age}" style="text-overflow: ellipsis;" />
</div>
</div>
</igc-expansion-panel>
`;
}
}, false);
이 구성의 결과는 다음과 같습니다.
Working with Flat Data Overview
The flat data binding approach is similar to the one that we already described above, but instead of cell value we are going to use the Data property of the IgbGridRow.
Since the Blazor grid is a component for rendering, manipulating and preserving data records, having access to every data record gives you the opportunity to customize the approach of handling it. The data property provides you this opportunity.
다음은 우리가 사용할 데이터입니다.
public class CustomersData : List<CustomersDataItem>
{
public CustomersData()
{
this.Add(new CustomersDataItem()
{
ID = "ALFKI",
CompanyName = "Alfreds Futterkiste",
ContactName = "Maria Anders",
ContactTitle = "Sales Representative",
Address = "Obere Str. 57",
City = "Berlin",
Region = "East",
PostalCode = "12209",
Country = "Germany",
Phone = "030-0074321",
Fax = "030-0076545"
});
}
}
맞춤 템플릿:
<IgbColumn Header="Address" Field="Address"
Editable="true"
BodyTemplateScript="AddressCellTemplate" />
//In JavaScript:
igRegisterScript("AddressCellTemplate", (ctx) => {
var html = window.igTemplating.html;
return html`<div class="address-container">
<div class="country-city">
<span><strong>Country:</strong> ${ctx.cell.row.data.Country}</span>
<br>
<span><strong>City:</strong> ${ctx.cell.row.data.City}</span>
</div>
<div class="phone-pscode">
<span><strong>Postal Code:</strong> ${ctx.cell.row.data.PostalCode}</span>
<br>
<span><strong>Phone:</strong> ${ctx.cell.row.data.Phone}</span>
</div>
<br />
</div>`;
}, false);
위에서 정의한 템플릿으로는 편집 작업을 수행할 수 없으므로 편집기 템플릿이 필요합니다.
<IgbColumn Header="Address" Field="Address"
Editable="true"
InlineEditorTemplateScript="AddressEditCellTemplate" />
//In JavaScript:
igRegisterScript("AddressEditCellTemplate", (ctx) => {
var html = window.igTemplating.html;
window.keyUpHandler = function() {
ctx.cell.row.data[window.event.target.id] = window.event.target.value;
}
return html`<div class="address-container--edit">
<div>
<span><strong>Country:</strong></span>
<input id='Country' onkeyup='keyUpHandler()' value="${ctx.cell.row.data.Country}"></input>
<br>
<span><strong>City:</strong></span>
<input id='City' onkeyup='keyUpHandler()' value="${ctx.cell.row.data.City}"></input>
</div>
<div>
<span><strong>Postal Code:</strong></span>
<input id='PostalCode' onkeyup='keyUpHandler()' value="${ctx.cell.row.data.PostalCode}"></input>
<br>
<span><strong>Selected:</strong></span>
<input id='Phone' onkeyup='keyUpHandler()' value="${ctx.cell.row.data.Phone}"></input>
</div>
<br>
</div>`;
}, false);
Working with Flat Data Example
Using code snippets from previous section will result in the following example of IgbGrid
Keyboard Navigation
Keyboard navigation of the IgbGrid provides a rich variety of keyboard interactions for the user. It enhances accessibility and allows intuitive navigation through any type of elements inside (cell, row, column header, toolbar, footer, etc.).
Styling Blazor Grid
참고: 그리드는 css 그리드 레이아웃을 사용하며 접두사가 없는 IE에서는 지원되지 않으므로 제대로 렌더링되지 않습니다.
<IgbGrid Class="grid"></IgbGrid>
Then set the --header-background and --header-text-color CSS properties for that class:
.grid {
--header-background: #494949;
--header-text-color: #FFF;
}
Known Limitations
| 한정 | 설명 |
|---|---|
열 너비 설정percentage 그리고px |
현재 우리는 열 너비와 열 너비의 혼합을 지원하지 않습니다.% 그리고px. |
유형의 열을 필터링하려고 할 때number |
값과 다른 경우number 필터링 입력에 입력됩니다.NaN 잘못된 캐스트로 인해 반환됩니다. |
그리드width 열 너비에 의존하지 않습니다 |
그만큼width 모든 열의 개수는 그리드 자체의 범위를 결정하지 않습니다. 이는 상위 컨테이너 크기 또는 정의된 그리드에 의해 결정됩니다.width. |
| 상위 컨테이너에 중첩된 그리드 | 그리드의 경우width 설정되지 않고 정의된 크기의 상위 컨테이너에 배치되면 그리드는 이 컨테이너까지 확장됩니다. |
열에는 허용되는 최소 열 너비가 있습니다. CSS 변수에--ig-size 따라 다음과 같습니다."작은": 56px "중간": 64px "대형": 80px |
너비가 허용되는 최소값보다 작게 설정되면 렌더링된 요소에 영향을 미치지 않습니다. 해당 항목에 대해 허용되는 최소 너비로 렌더링됩니다.--ig-size. 이로 인해 수평 가상화에서 예기치 않은 동작이 발생할 수 있으므로 지원되지 않습니다. |
| 행 높이는 현재 보기에 렌더링되지 않은 셀의 높이에 영향을 받지 않습니다. | 가상화로 인해 보기에 없는 사용자 지정 템플릿(셀 높이 변경)이 있는 열은 행 높이에 영향을 주지 않습니다. 행 높이는 보기에서 관련 열이 스크롤되는 동안에만 영향을 받습니다. |
API References
Additional Resources
우리 커뮤니티는 활동적이며 항상 새로운 아이디어를 환영합니다.