Angular 마스터-디테일 그리드
igxGrid
구성 요소는 콘텐츠를 확장/축소하여 특정 행에 대한 추가 세부 정보를 표시하는 세부 템플릿 지정을 지원합니다. 지정되면 각 레코드는 마스터 역할을 하며 확장 시 현재 레코드에 대한 상황별 데이터가 포함된 사용자 정의 가능한 세부 정보 템플릿을 표시합니다.
이 모드는 마스터-디테일 스타일 데이터를 계층 구조로 표시해야 할 때 유용합니다.
Angular 그리드 마스터-디테일 예제
import { Component, ViewChild } from '@angular/core' ;
import { IgxColumnComponent, IgxGridComponent, IgxGridDetailTemplateDirective, IgxTabsComponent, IgxTabItemComponent, IgxTabHeaderComponent, IgxTabHeaderLabelDirective, IgxTabContentComponent, IgxAvatarComponent, IgxDividerDirective } from 'igniteui-angular' ;
import { IgxLegendComponent, IgxPieChartCoreModule, IgxLegendModule, IgxCategoryChartCoreModule } from 'igniteui-angular-charts' ;
import { employeesData } from '../../data/employeesData' ;
import { IgxPreventDocumentScrollDirective } from '../../directives/prevent-scroll.directive' ;
@Component ({
selector : 'app-grid-master-detail' ,
styleUrls : ['./grid-master-detail.component.scss' ],
templateUrl : 'grid-master-detail.component.html' ,
imports : [IgxGridComponent, IgxPreventDocumentScrollDirective, IgxColumnComponent, IgxGridDetailTemplateDirective, IgxTabsComponent, IgxTabItemComponent, IgxTabHeaderComponent, IgxTabHeaderLabelDirective, IgxTabContentComponent, IgxAvatarComponent, IgxDividerDirective, IgxPieChartCoreModule, IgxLegendModule, IgxCategoryChartCoreModule]
})
export class GridMasterDetailSampleComponent {
@ViewChild ('legend' , { static : true })
public legend: IgxLegendComponent;
public data = [];
public include = ['date' , 'estimated' , 'actual' ];
constructor ( ) {
this .data = employeesData;
}
public getHeight (selectedIndex ) {
switch (selectedIndex) {
case 0 : return 250 ;
case 1 : return 320 ;
case 2 : return 400 ;
default : return 250 ;
}
}
public formatPieLabel = (args ) => args.item.Value + ' ' + args.item.Label;
public formatDateLabel(item: any ): string {
return item.date.toLocaleDateString(undefined , { month : 'short' });
}
public formatValue(val: any ): string {
return val.toLocaleString('en-us' , { maximumFractionDigits : 2 });
}
public getPieData (dataItem ) {
return [
{ Label : 'Won' , Value : dataItem.deals_won },
{ Label : 'Lost' , Value : dataItem.deals_lost },
{ Label : 'Pending' , Value : dataItem.deals_pending }];
}
public getChartData (dataItem ) {
const year: number = new Date ().getFullYear();
const sales: any [] = [];
for (let i = 0 ; i < 12 ; i++) {
const value = this .getRandomNumber(2000 , 10000 );
sales.push({
estimated : value + this .getRandomNumber(-2000 , 1000 ),
actual : value, date : new Date (year, i, 1 )
});
}
dataItem.chartData = sales;
return dataItem.chartData;
}
public gridData (dataItem ) {
const detailsData = [];
let won = dataItem.deals_won;
let lost = dataItem.deals_lost;
let pending = dataItem.deals_pending;
for (let j = 0 ; j < 3 ; j++) {
detailsData.push({
Q : 'Q' + (j + 1 ),
Won : this .getRandomNumber(0 , won),
Lost : this .getRandomNumber(0 , lost),
Pending : this .getRandomNumber(0 , pending)
});
won -= detailsData[j].Won;
lost -= detailsData[j].Lost;
pending -= detailsData[j].Pending;
}
detailsData.push({
Q : 'Q4' ,
Won : won,
Lost : lost,
Pending : pending
});
dataItem.gridData = detailsData;
return dataItem.gridData;
}
public columnInit (event: IgxColumnComponent ) {
if (event.field === 'Q' ) {
event.width = '50px' ;
event.header = ' ' ;
}
}
public getRandomNumber(min: number , max : number ): number {
return Math .round(min + Math .random() * (max - min));
}
}
ts コピー <div class ="grid__wrapper" >
<igx-grid [igxPreventDocumentScroll ]="true" [data ]="data" [autoGenerate ]="false" height ="592px" width ="100%" >
<igx-column field ="name" header ="Name" width ="250px" > </igx-column >
<igx-column field ="position" header ="Position" > </igx-column >
<igx-column field ="company" header ="Company" > </igx-column >
<igx-column field ="email" header ="Email" > </igx-column >
<igx-column field ="referred_by" header ="Referrer" > </igx-column >
<ng-template igxGridDetail let-dataItem >
<div style ="width:100%;" (keydown )='$event.stopPropagation()' [style.height.px ]='getHeight(tabs.selectedIndex)' >
<igx-tabs #tabs [selectedIndex ]="0" >
<igx-tab-item >
<igx-tab-header >
<span igxTabHeaderLabel > Details</span >
</igx-tab-header >
<igx-tab-content >
<div class ="tabContent" >
<div class ="avatarContainer" >
<igx-avatar src ="{{dataItem.avatar}}"
shape ="square" size ="large" > </igx-avatar >
<h6 > {{dataItem.name}}</h6 >
</div >
<igx-divider [vertical ]="true" > </igx-divider >
<div class ="tabInnerContent" >
<div class ="breathingcontent" >
<div > <span
class ="categoryStyle" > Country: </span > <span > {{dataItem.country}}</span >
</div >
<div > <span class ="categoryStyle" > City: </span > <span > {{dataItem.city}}</span >
</div >
<div > <span
class ="categoryStyle" > Street: </span > <span > {{dataItem.street}}</span >
</div >
<div > <span class ="categoryStyle" > Work
Phone: </span > <span > {{dataItem.work_phone}}</span > </div >
<div > <span class ="categoryStyle" > Mobile
Phone: </span > <span > {{dataItem.mobile_phone}}</span > </div >
</div >
</div >
</div >
</igx-tab-content >
</igx-tab-item >
<igx-tab-item >
<igx-tab-header >
<span igxTabHeaderLabel > Deals</span >
</igx-tab-header >
<igx-tab-content >
<div class ="tabContent" >
<igx-pie-chart [dataSource ]="getPieData(dataItem)" [formatLabel ]="formatPieLabel"
[outlines ]="['transparent']"
[brushes ]="['rgb(171, 223, 29)', 'rgb(228, 19, 16)', 'rgb(0, 111, 138)']"
class ="details-chart" labelsPosition ="insideEnd" leaderLineVisibility ="collapsed"
labelMemberPath ="Label" valueMemberPath ="Value" >
</igx-pie-chart >
<igx-divider [vertical ]="true" > </igx-divider >
<igx-grid [data ]="dataItem.gridData ? dataItem.gridData: gridData(dataItem)"
[autoGenerate ]="true" class ="details-grid" columnWidth ="70px"
width ="260px" height ="206px" (columnInit )="columnInit($event)" >
</igx-grid >
</div >
</igx-tab-content >
</igx-tab-item >
<igx-tab-item >
<igx-tab-header >
<span igxTabHeaderLabel > Sales</span >
</igx-tab-header >
<igx-tab-content >
<div class ="tabContent" style ="flex-direction: column;" >
<igx-legend #legend orientation ="horizontal" > </igx-legend >
<igx-category-chart height ="250px" [legend ]="legend"
[dataSource ]="dataItem.chartData ? dataItem.chartData : getChartData(dataItem)"
chartType ="Line" chartTitle ="Sales" subtitle ="(Estimated, Actual)" xAxisInterval ="1"
[brushes ]="['rgb(0, 111, 138)', 'rgb(171, 223, 29)']"
[xAxisFormatLabel ]="formatDateLabel" [includedProperties ]="include"
[crosshairsSnapToData ]="false"
[crosshairsDisplayMode ]="'Both'" [crosshairsAnnotationEnabled ]="true"
isHorizontalZoomEnabled ="false" isVerticalZoomEnabled ="false" >
</igx-category-chart >
</div >
</igx-tab-content >
</igx-tab-item >
</igx-tabs >
</div >
</ng-template >
</igx-grid >
</div >
html コピー @use '../../../variables' as *;
.categoryStyle {
font-weight : 600 ;
}
.tabContent {
padding : rem(24px ) rem(8px );
display : flex;
justify-content : flex-start;
margin : rem(10px );
}
.avatarContainer {
display : flex;
align-items : center;
flex-direction : column;
}
igx-divider {
margin : 0 rem(24px ) !important ;
}
h6 {
margin-top : 1em ;
}
.details-chart {
width : rem(200px );
background : contrast-color($color : 'gray' , $variant : 900 );
background : contrast-color($color : 'gray' , $variant : 900 );
padding : rem(16px );
border-radius : rem(4px );
border : rem(1px ) solid contrast-color($color : 'gray' , $variant : 900 );
}
.tabContent igx-grid {
box-shadow : none;
border : rem(1px ) solid contrast-color($color : 'gray' , $variant : 900 );
}
.grid__wrapper {
--ig-size: var(--ig-size-medium);
margin : rem(4px ) rem(16px );
}
scss コピー
이 샘플이 마음에 드시나요? 전체 Ignite UI for Angular 툴킷에 액세스하고 몇 분 안에 나만의 앱을 구축해 보세요. 무료로 다운로드하세요.
구성
마스터-디테일 모드로 표시되도록 igxGrid
구성하려면 igxGridDetail
지시문으로 표시된 그리드 내부의 템플릿을 지정해야 합니다.
<igx-grid ... >
<ng-template igxGridDetail let-dataItem >
</ng-template >
</igx-grid >
html
템플릿의 컨텍스트는 마스터 레코드 데이터이므로 마스터 레코드의 값을 세부 템플릿에 표시할 수 있습니다. 예를 들어:
<igx-grid ... >
<ng-template igxGridDetail let-dataItem >
<div *ngIf ="dataItem.Category" >
<header > {{dataItem.Category.CategoryName}}</header >
<span > {{dataItem.Category.Description}}</span >
</div >
</ng-template >
</igx-grid >
html
API
확장 상태는 다음을 통해 제어할 수 있습니다. expansionStates
의 입력 igxGrid
. 상태는 키-값 쌍[행 식별자, 확장 상태]에 저장됩니다. 이 속성은 현재 확장 상태를 가져오거나 설정하고 양방향 바인딩을 지원합니다.
<igx-grid [(expansionStates )]='expansionState' >
...
</igx-grid >
html
확장 상태를 제어하기 위한 추가 API 메소드도 공개됩니다.
키보드 탐색
알려진 문제 및 제한 사항
알려진 제한 사항
설명
다음 초점 요소가 표시되는 뷰 포트 외부에 있는 경우 사용자 정의 세부 사항 템플릿 내부의 탭 탐색이 마스터 그리드 스크롤 위치를 업데이트하지 못할 수 있습니다.
사용자 정의 세부 템플릿 내부의 탭 탐색은 브라우저에 달려 있습니다.
세부정보 보기 내에서 그리드를 템플릿으로 만들 때<igx-column>
정의에 따라 상위 그리드도 해당 열을 렌더링합니다.
중첩된 그리드에 대해 autoGenerate=true를 사용하면 이 문제를 피할 수 있습니다. 해당 열의 일부 측면을 수정해야 하는 경우columnInit
이벤트를 사용할 수 있습니다.
세부정보 템플릿은 Excel로 내보내지지 않습니다.
세부 정보 템플릿에는 모든 유형의 콘텐츠가 포함될 수 있으므로 기본적으로 Excel로 내보낼 수 없습니다.
검색 기능은 세부 정보 템플릿의 요소를 강조 표시하지 않습니다.
API 참조