Отображение массивов объектов в столбце сетки кендо - PullRequest
2 голосов
/ 07 мая 2019

Я должен отображать данные в сетке, которая должна отображать весь массив в одном столбце.

Для ясности рассмотрим в качестве минимального примера следующую структуру данных:

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];

Я хочу отобразить людей в сетке. Что касается навыков, я хочу показать только описание, а не идентификатор. Результат должен выглядеть примерно так:

Name    Nicknames   Skills 

John    Johnny      Angular, Javascript  
Robert  Bob, Rob    Angular

Я подумал об использовании * ngFor, но это приводит к ошибке: «Не удается найти другой поддерживающий объект« [объект-объект] »типа« объект ». NgFor поддерживает только привязку к итерациям, таким как массивы». Похоже, 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>

Интересно, что если я не использую шаблон, я получаю [объект объекта] для каждого навыка . Но если я использую шаблон и отображаю {{dataItem}}, это приводит к single [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. Это приведет к большому количеству конверсий при работе с моими более сложными реальными данными.

1 Ответ

1 голос
/ 08 мая 2019

Используя шаблон ячейки , я смог получить желаемый результат, пожалуйста, проверьте следующий фрагмент кода.

@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]
    }
];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...