angular - 在剑道网格列中显示对象数组
问题描述
我必须在需要在一列中显示整个数组的网格中显示数据。
为了清楚起见,请考虑以下数据结构的最小示例:
export class Person {
public Name: string;
public Nicknames: string[];
public Skills: Skill[];
constructor(name: string, nicknames: string[], skills: Skill[]) {
this.Name = name;
this.Nicknames = nicknames;
this.Skills = skills;
}
}
export class Skill {
public Id: number;
public Description: string;
constructor(id: number, description: string) {
this.Id = id;
this.Description = description;
}
}
人们可以拥有多种技能,其中技能是一种复杂的数据结构(与只是字符串的昵称相反)。
我们用两个人定义一个数据源:
// define skills
const angular = new Skill(1, 'Angular');
const js = new Skill(2, 'Javascript');
// define persons having these skills
const alice = new Person('John', ['Johnny'], [angular, js]);
const bob = new Person('Robert', ['Bob', 'Rob'], [angular]);
// set gridData
this.gridData = [alice, bob];
我想在网格上显示这些人。对于技能,我只想显示描述,而不是 Id。结果应如下所示:
Name Nicknames Skills
John Johnny Angular, Javascript
Robert Bob, Rob Angular
我曾想过使用 *ngFor,但这会导致错误:“找不到类型为 'object' 的不同支持对象 '[object Object]'。NgFor 仅支持绑定到 Iterables,例如数组。” 似乎 dataItem 不再是一个数组。
<kendo-grid [data]="gridData" [columnMenu]="false">
<kendo-grid-column field="Name" title="Name"></kendo-grid-column>
<!--No problems with a simple string array-->
<kendo-grid-column field="Nicknames" title="Nicknames"></kendo-grid-column>
<!--Using ngFor result in error-->
<kendo-grid-column field="Skills" title="Skills with ngFor">
<ng-template kendoGridCellTemplate let-dataItem>
<div *ngFor="let skill of dataItem">{{skill.Description}}</div>
</ng-template>
</kendo-grid-column>
</kendo-grid>
有趣的是,如果我不使用模板,我会为每个技能获得一个 [object Object] 。但是,如果我使用模板并显示 {{dataItem}},则会产生单个[object Object]。
<!--Not using a template results in [object Object] per skill-->
<kendo-grid-column field="Skills" title="Skills w/o template"></kendo-grid-column>
<!--dataItem seems to be a SINGLE [object Object]-->
<kendo-grid-column field="Skills" title="Skills dataItem">
<ng-template kendoGridCellTemplate let-dataItem>
{{dataItem}}
</ng-template>
</kendo-grid-column>
知道如何显示数组并对其应用一些模板代码(例如仅显示描述)吗?
扁平化数据并将其存储在扁平数据源中(大多数示例都是这样做的)不是一种选择,因为我从后端接收数据,并且我还需要将数据发布回 API。在处理我更复杂的真实数据时,这将导致大量转换。
解决方案
使用单元格模板,我能够获得所需的输出,请检查以下代码片段。
@Component({
selector: 'my-app',
template: `
<kendo-grid [data]="gridData">
<kendo-grid-column field="ProductName">
</kendo-grid-column>
<kendo-grid-column field="Discontinued">
<ng-template kendoGridCellTemplate let-dataItem let-rowIndex="rowIndex">
<span
class="{{dataItem.Discontinued ? 'discontinued' : 'active'}}">
{{dataItem.Discontinued ? "discontinued" : "active"}}
</span>
</ng-template>
</kendo-grid-column>
<kendo-grid-column field="MoreData">
<ng-template kendoGridCellTemplate let-dataItem let-rowIndex="rowIndex">
<span *ngFor="let item of dataItem.MoreData;let i = index">
{{item.Description}}
<label *ngIf="(dataItem.MoreData.length-1)>i">,</label>
</span>
</ng-template>
</kendo-grid-column>
</kendo-grid>
`
})
export class AppComponent {
public gridData: any[] = sampleProducts;
}
export class MoreData {
public Id: number;
public Description: string;
constructor(id: number, description: string) {
this.Id = id;
this.Description = description;
}
}
const moreData1 = new MoreData(1, 'Data 1');
const moreData2 = new MoreData(2, 'Data 2');
const moreData3 = new MoreData(3, 'Data 3');
const moreData4 = new MoreData(4, 'Data 4');
const moreData5 = new MoreData(5, 'Data 5');
export const sampleProducts = [
{
"ProductID": 1,
"ProductName": "Chai",
"SupplierID": 1,
"CategoryID": 1,
"QuantityPerUnit": "10 boxes x 20 bags",
"UnitPrice": 18,
"UnitsInStock": 39,
"UnitsOnOrder": 0,
"ReorderLevel": 10,
"Discontinued": false,
"Category": {
"CategoryID": 1,
"CategoryName": "Beverages",
"Description": "Soft drinks, coffees, teas, beers, and ales"
},
"FirstOrderedOn": new Date(1996, 8, 20),
"MoreData": [moreData1,moreData2,moreData3,moreData4]
},
{
"ProductID": 2,
"ProductName": "Chang",
"SupplierID": 1,
"CategoryID": 1,
"QuantityPerUnit": "24 - 12 oz bottles",
"UnitPrice": 19,
"UnitsInStock": 17,
"UnitsOnOrder": 40,
"ReorderLevel": 25,
"Discontinued": false,
"Category": {
"CategoryID": 1,
"CategoryName": "Beverages",
"Description": "Soft drinks, coffees, teas, beers, and ales"
},
"FirstOrderedOn": new Date(1996, 7, 12),
"MoreData": [moreData2,moreData3]
},
{
"ProductID": 3,
"ProductName": "Aniseed Syrup",
"SupplierID": 1,
"CategoryID": 2,
"QuantityPerUnit": "12 - 550 ml bottles",
"UnitPrice": 10,
"UnitsInStock": 13,
"UnitsOnOrder": 70,
"ReorderLevel": 25,
"Discontinued": false,
"Category": {
"CategoryID": 2,
"CategoryName": "Condiments",
"Description": "Sweet and savory sauces, relishes, spreads, and seasonings"
},
"FirstOrderedOn": new Date(1996, 8, 26),
"MoreData": [moreData1,moreData2]
},
{
"ProductID": 4,
"ProductName": "Chef Anton's Cajun Seasoning",
"SupplierID": 2,
"CategoryID": 2,
"QuantityPerUnit": "48 - 6 oz jars",
"UnitPrice": 22,
"UnitsInStock": 53,
"UnitsOnOrder": 0,
"ReorderLevel": 0,
"Discontinued": false,
"Category": {
"CategoryID": 2,
"CategoryName": "Condiments",
"Description": "Sweet and savory sauces, relishes, spreads, and seasonings"
},
"FirstOrderedOn": new Date(1996, 9, 19),
"MoreData": [moreData3,moreData4]
},
{
"ProductID": 5,
"ProductName": "Chef Anton's Gumbo Mix",
"SupplierID": 2,
"CategoryID": 2,
"QuantityPerUnit": "36 boxes",
"UnitPrice": 21.35,
"UnitsInStock": 0,
"UnitsOnOrder": 0,
"ReorderLevel": 0,
"Discontinued": true,
"Category": {
"CategoryID": 2,
"CategoryName": "Condiments",
"Description": "Sweet and savory sauces, relishes, spreads, and seasonings"
},
"FirstOrderedOn": new Date(1996, 7, 17),
"MoreData": [moreData5]
}
];
推荐阅读
- sql - 当我从 APEX 上的用户列表中选择 user_name 时,如何更新 user_ID?
- ios - SwiftUI AVPlayer - 如何暂停和恢复播放?
- perl - Binance::API:无法连接到交易所
- python - 使用 python 液化图像,如 Photoshop
- docker - 通过 packer 构建 docker 容器并通过 chef-solo 进行配置在启动服务时失败
- .net-core - .NET Core 将 API 从 2.2 迁移到 3.1 DateTimeOffset 问题
- numpy - 如何在 numba 装饰函数中使用布尔一维数组对一维数组进行子集化?
- performance - How can I fix google page speed LCP problem
- python - Select rows from a dataframe using another dataframe column
- c++ - What to do with error: cannot find ltinfo