Как создать модель данных в angular / typescript, содержащую вложенные объекты

#angular #typescript

#angular #typescript

Вопрос:

Я получаю массив json из api.

 [
    {
        id: 1,
        parentId: null,
        name: 'category 1' 

    },
    {
        id: 2,
        parentId: null,
        name: 'category 2' 

    }
]
  

итак, после получения этих данных я использую этот идентификатор и вызываю API для получения дочерних элементов.

 [
    {
        id: 11,
        parentId: null,
        name: 'category 1 child 1' 

    },
    {
        id: 12,
        parentId: null,
        name: 'category 1 child 2' 

    }
]
  

далее я использую идентификатор этих дочерних элементов, чтобы получить дочерние элементы.

 [
    {
        id: 21,
        parentId: null,
        name: 'child 1 sub child 1' 

    },
    {
        id: 22,
        parentId: null,
        name: 'child 1 sub child 2' 

    }
]
  

итак, у каждого дочернего элемента есть свои собственные дочерние элементы. окончательное то, что я хочу.

 [
    {
        id: 1,
        parentId: null,
        name: 'category 1',
        children: [
            {
                id: 11,
                parentId: null,
                name: 'category 1 child 1',
                [
                    {
                        id: 11,
                        parentId: null,
                        name: 'category 1 child 1',
                        children: // further children  

                    },
                    {
                        id: 12,
                        parentId: null,
                        name: 'category 1 child 2',
                        children: // further children

                    }
                ] 

            },
            {
                id: 12,
                parentId: null,
                name: 'category 1 child 2',
                children: // same as above 

            }
        ] 

    },
    {
        id: 2,
        parentId: null,
        name: 'category 2' 

    }
]
  

чего я пытаюсь достичь, так это моей категории и дочерних интерфейсов и моделей

 export interface ICategory {
  id?: any;
  parentId?: number;
  name?: string;
  children: Children[]
}

export class Category implements ICategory {
  public id?: any;
  public parentId?: number;
  public name?: string;
  public children: Children[]

  constructor(data: ICategory) {
    Object.assign(this, data);
  }
}


export interface IChildren {
  id?: any;
  parentId?: number;
  name?: string;
  children: Children[]
}

export class Children implements IChildren {
  public id?: any;
  public parentId?: number;
  public name?: string;
  public children: Children[]

  constructor(data: IChildren) {
    Object.assign(this, data);
  }
}
  

Пожалуйста, помогите мне, я новичок в angular и typescript.
Спасибо

Ответ №1:

Нет необходимости создавать несколько интерфейсов, достаточно одного интерфейса. Я просто даю вам предложение с type приведенным ниже, и вы можете проверить stackblitz, чтобы попытаться добавить больше дочерних элементов

Просто введите дочерние элементы также как ICategory массив -> ICategory[]

 export type Category = {
  id: number;
  parentId: null | number;
  name: string;
  children: Category[];
};

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  name = "Angular "   VERSION.major;

  objs: Category[] = [{
    id: 1,
    parentId: 0,
    name: "parent 1",
    children: [{
      id: 2,
      parentId: 1,
      name: "Child 1",
      children: [{
        id: 3,
        parentId: 2,
        name: "Sub Child 1",
        children: []
      }]
    }]
  }];
}
  

Ответ №2:

Вам нужен только один интерфейс, и в TypeScript мы не используем префикс I, как в соглашениях C # / JAVA.

Вот начальная функция, ей нужно добавить дочерний элемент. Я мог бы закончить это позже, но мне нужно идти.

 export interface Category {
  id?: any;
  parentId?: number;
  name?: string;
  children: Category[]
}
  

 const first = [
    {
        id: 1,
        parentId: null,
        name: 'category 1' 
    },
    {
        id: 2,
        parentId: null,
        name: 'category 2' 

    }
];

const second = [
    {
        id: 11,
        parentId: null,
        name: 'category 1 child 1' 

    },
    {
        id: 12,
        parentId: null,
        name: 'category 1 child 2' 

    }
];

const third = [
    {
        id: 21,
        parentId: null,
        name: 'child 1 sub child 1' 

    },
    {
        id: 22,
        parentId: null,
        name: 'child 1 sub child 2' 
    }
];

const addChildren = (parent, child) => parent.reduce((results, current) => {
  const children = child.find(c => c.name.endsWith('child '   current.id));
  results.push({ ...current, children: children });
  return results;
}, []);

console.log(addChildren(first, addChildren(second, third)));  

Ответ №3:

Вы можете использовать библиотеку class-transformer . Отличный пакет, который упрощает создание модели данных.

Пример:

 import { Type } from 'class-transformer';

export class Employee {
    firstName: string;
    email: string;
    days: string;
    hours: string;

    @Type(() => Availability)
    availablity: Availablity

    constructor(args: Employee) {
      Object.assign(this, args);
    }
}

export class Availability {
    days: string;
    hours: string;

    constructor(args: Availability) {
      Object.assign(this, args);
    }
}
  

Как вы можете видеть, с помощью этого пакета мы можем использовать type декоратор, который позволяет нам преобразовывать вложенный объект. Вы можете ознакомиться с более подробной информацией здесь.

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