Как видно из названия, у меня есть рекурсивно созданная группа компонентов.Компоненты основаны на древовидной модели данных под названием Item и создаются во вложенных списках путем рекурсивного вызова шаблона и передачи вложенных массивов моей модели в виде значений @Input ().Хотя это работает нормально, проблема заключается в том, что манипулирование данными (которые хранятся в list.service.ts), которые определяют, сколько раз создается этот шаблон, вызывает определенные ошибки.У меня есть две кнопки, прикрепленные к двум функциям.Один удаляет определенный элемент и перемещает оставшиеся элементы вверх в дереве элементов.Это отлично работает.Другая кнопка должна удалять все элементы в массиве элементов данного элемента, эффективно удаляя его дочерние элементы.Интересно, что функция «удаление и смещение» работает правильно, только если я использую тему и подписку для своих услуг и компонентов.Хотя функция «удалить детей» работает правильно только в том случае, если я не пользуюсь подпиской.Вместо этого кажется, что он уничтожает экземпляр компонента экземпляра компонента, на котором я нажал «удалить дочерние элементы» (этого не должно происходить, поскольку я не удаляю этот элемент, а просто массив элементов), а затем перестраиваем вложенные компоненты из корневого компонента.,
Например, если у меня были следующие вложенные массивы элементов, отображаемые моими компонентами в DOM:
, и я нажал кнопку Удалить детей на элементе 3, яожидал, что onDestroy будет вызываться для элемента 4, оставляя элементы 1, 2 и 3 нетронутыми, однако в конечном итоге он будет выглядеть так:
О чем я хотел бы спросить любогокто более осведомлен о хуках жизненного цикла Angular 2, чем я: 1) почему подписка мешает правильной работе функции удаления детей, 2) почему дерево элементов перестраивается из корневого узла всякий раз, когда я нажимаю кнопку «Удалить детей», и3) как мне изменить код для решения этой проблемы?
item.model.ts
export class Item{
constructor(public id: number, public details: string, public date: Date, public items?: Item[]){}
}
item-list.component.html
<div *ngFor="let item of items">
<ul>
<li> {{item.details}}
<br>
<button (click)="onDelete(item.id)">Delete</button>
<button (click)="onDeleteChildren(item.id)">
Delete Children</button>
<app-item-list [items]="item.items" *ngIf="item.items">
</app-item-list>
</li>
</ul>
</div>
item-list.component.ts
@Input() items: Item[] = [];
listSubscription: Subscription;
constructor(private list: ListService) {
this.items = this.list.getItems();
console.log('constructor called');
this.listSubscription = this.list.listUpdated.subscribe(
(items: Item[]) => {
this.items = items;
}
);
}
onDelete(index: number) {
this.list.deleteItemAndShiftChildren(index);
}
onDeleteChildren(index: number) {
this.list.deleteChildItems(index);
}
список.service.ts
deleteChildItems(index: number) {
this.recursiveChildDelete(this.items, index);
this.listUpdated.next(this.items.slice());
}
deleteItemAndShiftChildren(index: number) {
this.recursiveChildShift(this.items, this.items[0], index);
this.listUpdated.next(this.items.slice());
}
recursiveChildDelete(items: Item[], index: number) {
items.forEach( element => {
if (element.id === index) {
if(element.items){
element.items = [];
}
} else if (element.items) {
this.recursiveChildDelete(element.items, index);
}
});
}
recursiveChildShift(items: Item[], oldItem: Item, index: number) {
items.forEach( element => {
// if the id of the element to be deleted is found
if (element.id === index) {
//if the deleted element is the root node
if(oldItem==element){
if(element.items){
this.items = element.items;
return;
} else {
this.items = [];
return;
}
}
oldItem.items = element.items;
return;
} else if (element.items) {
oldItem = element;
this.recursiveChildShift(element.items, oldItem, index);
}
});
}