Как расширить класс (добавить новый атрибут к объекту класса) программно? Следующая ситуация: Предположим есть следующие классы (псевдокод TypeScript):class Project { id: number; name: string; stages: Stage[]; constructor() { this.stages = [] } } class Stage { id: number; name: string; jobs: Job[]; constructor() { this.jobs= [] } } class Job { id: number; name: string; } У нас есть список проектов (Project[]), к которому привязаны этапы работ (Stage[]), к которым привязаны конкретные работы (Job[]). Есть форма со списком проектов, можно провалиться в конкретный проект. На форме изменения проекта можно к проекту привязать (добавить) конкретные этапы и работы, отметив их чекбоксами. Но в классах Stage и Jobs нет атрибута checked: boolean. Как программно добавить атрибут? Как и где хранить объеты, у которых checked === true, чтобы потом put запросом обновить проект на бэкенде? Вот небольшой пример компоненты на Angular: @Component export class ProjectFormComponent implements OnInit { constructor (private projectService: ProjectService) { } projects: Projects[];
onInit() { this.projectService.getPorjects() .subscribe(projects => this.projects = projects); } OnEditProjectButtonClick(project) { this.projectService.getStageByProjectID(project) .subscribe(stages => { project.stages = stages (как то нужно добавить атрибут checked к объекту stages) project.stages.filter(stage => stage.checked) (но у нас нет свойства checked) } } } Шаблон:
Чтобы добавить атрибут "checked" к объекту Stage программно, вам нужно создать интерфейс или расширить класс Stage. В данном случае лучше использовать интерфейс, поскольку TypeScript не поддерживает множественное наследование классов.
Пример интерфейса с добавлением атрибута "checked":
Для хранения объектов, у которых checked === true, вы можете создать отдельный массив в вашем компоненте и добавлять в него объекты при изменении состояния чекбоксов. Например:
После того, как пользователь внес все изменения, вы можете отправить put запрос на бэкенд, передавая массив checkedStages для обновления данных проекта.
Чтобы добавить атрибут "checked" к объекту Stage программно, вам нужно создать интерфейс или расширить класс Stage. В данном случае лучше использовать интерфейс, поскольку TypeScript не поддерживает множественное наследование классов.
Пример интерфейса с добавлением атрибута "checked":
interface CheckedStage extends Stage {checked: boolean;
}
Затем в вашем компоненте, когда получаете этапы проекта, вы можете привести их к типу CheckedStage и установить атрибут "checked":
OnEditProjectButtonClick(project) {this.projectService.getStageByProjectID(project)
.subscribe(stages => {
project.stages = stages.map((stage: Stage) => ({
...stage,
checked: false
})) as CheckedStage[];
});
}
Теперь у вас есть атрибут "checked" у каждого этапа проекта. В шаблоне вы можете использовать его для отображения чекбоксов:
<ul><li *ngFor="let stage of project.stages">
<input type="checkbox" [checked]="stage.checked" (change)="stage.checked = !stage.checked">
{{stage.name}}
</li>
</ul>
Для хранения объектов, у которых checked === true, вы можете создать отдельный массив в вашем компоненте и добавлять в него объекты при изменении состояния чекбоксов. Например:
checkedStages: CheckedStage[] = [];onCheckboxChange(stage: CheckedStage) {
if (stage.checked) {
this.checkedStages.push(stage);
} else {
this.checkedStages = this.checkedStages.filter(s => s !== stage);
}
}
После того, как пользователь внес все изменения, вы можете отправить put запрос на бэкенд, передавая массив checkedStages для обновления данных проекта.