Вложенные дочерние элементы Mat-Tree не отображаются в Angular 9

#angular #typescript #angular-material #treenode

#angular #typescript #angular-материал #treenode

Вопрос:

я впервые публикую вопрос здесь, в stack overflow, и я надеюсь, что смогу получить некоторую помощь в решении моей проблемы с Mat-Tree, поскольку он не показывает дочерние элементы, хотя, когда я регистрирую консоль, данные есть.

Я получаю данные из сервиса и преобразовал данные, чтобы они были точно такими же, как модель, показанная в примере документации mat-tree.

 interface SampleNodeModel {
 id: number;
 name: string;
 type: string;
 children?: SampleNodeModel[];
}
  

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

 getData() {
     const dataArray = [];
     const tempModel = {} as SampleNodeModel;
     this.apiService.getSampleData().subscribe(res => {
     tempModel.id = res.id;
     tempModel.name = res.legalName;
     tempModel.type = 'Parent';
    
     const children = [];
    
     res.students.forEach(res2 => {
      const studentList = {} as SampleNodeModel;
      studentList.id = res2.id;
      studentList.name = res2.firstName   res2.lastName;
      studentList.type = 'Student';
      children.push(studentList);
     });
    
     res.teachers.forEach(res3 => {
      const teacherList = {} as SampleNodeModel;
      teacherList .id = res3 .id;
      teacherList .name = res3.firstName   res3.lastName;
      teacherList .type = 'Teacher';
      children.push(teacherList );
     });
    });
    
    tempModel.children = children;
    
    dataArray.push(tempModel);
    
    this.dataSource.data = dataArray;
}
  

И вот остальная часть файла TS для вашей справки:

 treeControl = new NestedTreeControl<SampleNodeModel>(node => node.children);
dataSource = new MatTreeNestedDataSource<SampleNodeModel>();

constructor(private apiService: ApiService) {
 this.getData(); // this is the function above for getting the data
}

hasChild = (_: number, node: SampleNodeModel) => node.children !== undefined amp;amp; node.children.length > 0;
  

И мой HTML-код точно такой же, как в примере для вложенного Mat-Tree. https://material.angular.io/components/tree/overview

Основываясь на приведенном выше коде, я сделал что-то не так? Когда я запускаю консоль.регистрируйте массив данных, я получаю данные в формате, точно таком же, как в модели.. Я часами пытался выяснить, где я ошибся, но, похоже, не могу его найти.

Когда я console.log, вот формат данных, которые я получаю:

 dataArray: 0: {children: Array(29), id: 101, name: 'School Name', type: 'Parent'}
  

Отображается только имя родительского элемента, но кнопки для переключения и отображения дочерних элементов там нет… Надеюсь, кто-нибудь сможет мне помочь! Спасибо!!!

Комментарии:

1. Не могли бы вы поделиться своим кодом в stackblitz? Чтобы я мог дебютировать.

2. @Muthupriya — я попытался поместить проект в stackblitz и воссоздать его, но я получаю сообщение об ошибке «/turbo_modules/@angular/material@10.1.3/index.d.ts ‘ не является модулем.».. Но я добавил свой код в stackblitz, а также реплицировал данные, которые я получаю из API в сервисах. Вот ссылка: [ссылка]< stackblitz.com/edit /… > Большое вам спасибо за попытку помочь мне!

3. Я разрешил ваш «/turbo_modules/@angular/material@10.1.3/index.d.ts проблема «не является модулем» и теперь может видеть ваши дочерние элементы. @hanzoac

4. @Muthupriya- спасибо за вашу помощь. Я фактически решил эту проблему и опубликую, как она была решена.

5. @Muthupriya — могу я узнать, как вы разрешили «/turbo_modules/@angular/material@10.1.3/index.d.ts проблема «не в модуле»? Спасибо!

Ответ №1:

Мы смогли, наконец, заставить дочерние элементы отображаться, удалив блок кода для вызова API в функции getData() и поместив его в ngOnInit, а функция getData() используется только для присвоения значения источнику данных, вызывается после завершения загрузки API.

Я не уверен в этом, но, возможно, причина в том, что я уже присваиваю значение источнику данных, когда загрузка API все еще не завершена (если я правильно это объясняю). В любом случае, вот изменения, которые мы внесли в мой код на основе кода в вопросе выше.

 treeControl = new NestedTreeControl<SampleNodeModel>(node => node.children);
dataSource = new MatTreeNestedDataSource<SampleNodeModel>();

dataArray = [];
tempModel = {} as SampleNodeModel;

constructor(private apiService: ApiService) {
}

ngOnInIt(): void {
 this.apiService.getSampleData().subscribe(res => {
     this.tempModel.id = res.id;
     this.tempModel.name = res.legalName;
     this.tempModel.type = 'Parent';
    
     const children = [];
    
     res.students.forEach(res2 => {
      const studentList = {} as SampleNodeModel;
      studentList.id = res2.id;
      studentList.name = res2.firstName   res2.lastName;
      studentList.type = 'Student';
      children.push(studentList);
     });
    
     res.teachers.forEach(res3 => {
      const teacherList = {} as SampleNodeModel;
      teacherList .id = res3 .id;
      teacherList .name = res3.firstName   res3.lastName;
      teacherList .type = 'Teacher';
      children.push(teacherList );
     });
     
    this.getData(); // calling the function after getting the data from the API     

    });

}

hasChild = (_: number, node: SampleNodeModel) => node.children !== undefined amp;amp; node.children.length > 0;

getData() {
    
    this.tempModel.children = children;
    this.dataArray.push(tempModel);
    this.dataSource.data = null;
    this.dataSource = new MatTreeNestedDataSource<SampleNodeModel>();
    this.dataSource.data = dataArray;
}