Angular 2: удаление рекурсивно-созданных компонентов как-то создает новые экземпляры компонентов - PullRequest
0 голосов
/ 06 июня 2018

Как видно из названия, у меня есть рекурсивно созданная группа компонентов.Компоненты основаны на древовидной модели данных под названием Item и создаются во вложенных списках путем рекурсивного вызова шаблона и передачи вложенных массивов моей модели в виде значений @Input ().Хотя это работает нормально, проблема заключается в том, что манипулирование данными (которые хранятся в list.service.ts), которые определяют, сколько раз создается этот шаблон, вызывает определенные ошибки.У меня есть две кнопки, прикрепленные к двум функциям.Один удаляет определенный элемент и перемещает оставшиеся элементы вверх в дереве элементов.Это отлично работает.Другая кнопка должна удалять все элементы в массиве элементов данного элемента, эффективно удаляя его дочерние элементы.Интересно, что функция «удаление и смещение» работает правильно, только если я использую тему и подписку для своих услуг и компонентов.Хотя функция «удалить детей» работает правильно только в том случае, если я не пользуюсь подпиской.Вместо этого кажется, что он уничтожает экземпляр компонента экземпляра компонента, на котором я нажал «удалить дочерние элементы» (этого не должно происходить, поскольку я не удаляю этот элемент, а просто массив элементов), а затем перестраиваем вложенные компоненты из корневого компонента.,

Например, если у меня были следующие вложенные массивы элементов, отображаемые моими компонентами в DOM:

  • item 1
    • item 2
      • элемент 3
        • элемент 4

, и я нажал кнопку Удалить детей на элементе 3, яожидал, что onDestroy будет вызываться для элемента 4, оставляя элементы 1, 2 и 3 нетронутыми, однако в конечном итоге он будет выглядеть так:

  • item 1
    • item 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);
      }
    });
  }

1 Ответ

0 голосов
/ 07 июня 2018

Оказалось, что для решения этой проблемы было два ключа:

1) Образцы данных, которые я использовал, были сделаны неправильно.У меня были одинаковые значения идентификаторов для двух элементов в моем массиве элементов, что приводило меня к странной ошибке при выполнении определенных операций.Поэтому я исправил это.

2) Я создал корневой компонент, который содержал подписку на массив в моем сервисе, который передавал свое значение дочернему компоненту, который рекурсивно генерировал список.Таким образом, у меня было только одно место, корень, который получал обновления от субъекта службы и собирал массив из этого корневого компонента.Как я и делал изначально, каждый компонент, являющийся частью дерева компонентов, подписывался на Subject в моем сервисе, что было неправильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...