在同一页面中多次使用相同的组件

时间:2018-12-28 12:38:19

标签: angular components

我开始使用Angular进行开发。 我用数据创建了一个API。此数据是这样排序的

对于每个“机构”,n个“培训”。 对于每个“培训”,n个“组”。 我通过服务请求API。

因此,我想在一个页面上显示一个扩展面板:https://material.angular.io/components/expansion/overview 培训作为标题和组列表相关联。

在代码中,我有显示“ n Training”的“ training-view.component”,在此培训中,我将n“ group-view.component”放入了

假设我接受了3次培训,我的站点将显示相同组的3次培训(图片更加清晰): http://puu.sh/CogJM/476c792726.png

我尝试过:Angular 2 : same component usage repeatedly 但是“唯一ID”不是解决方案。 也许我不能在同一页面中使用相同的组件,但是当我使用“ ngFor”时,它会起作用

所有代码都是代码的一部分。 Train-view.components.ts:

@Component({
selector: 'app-training-view',
templateUrl: './training-view.component.html',
styleUrls: ['./training-view.component.css']
})
export class TrainingViewComponent implements OnInit {

trainings: Training[];
trainingSubscription: Subscription;
[...]

ngOnInit() {

this.trainingSubscription = this.TrainingService.trainingsSubject.subscribe(
  (groups: any[]) => {
    this.trainings = groups;
  }
);
this.TrainingService.emitTrainingsSubject();

this.onFetch();
}

培训视图html

<mat-accordion>
    <mat-expansion-panel *ngFor="let training of trainings">
      <mat-expansion-panel-header>
        <mat-panel-title>
          {{training.name}}
        </mat-panel-title>
        <mat-panel-description>
          Liste des groupes
        </mat-panel-description>
      </mat-expansion-panel-header>
      <app-group-view
        [idTraining]="training.id"
        [id]="id" 
      ></app-group-view>

      </mat-form-field>
    </mat-expansion-panel>
  </mat-accordion>

app-group-view将获取所有组,并对“ groups.components”执行“ ngFor”

所以组视图ts

        import { Component, OnInit, Input } from '@angular/core';
    import { ActivatedRoute } from '@angular/router';
    import { GroupService } from '../services/group.service';
    import { Subscription } from 'rxjs';
    import { Group } from '../model/Group.model';


    let uniqueId = 0;
    @Component({
      selector: 'app-group-view',
      templateUrl: './group-view.component.html',
      styleUrls: ['./group-view.component.css']
    })
    export class GroupViewComponent implements OnInit {
      @Input() idTraining: number;
      id = "tr-" + uniqueId++;
      groups: Group[];
      groupSubscription: Subscription;
      idFormation = null;




      constructor(
        private GroupService: GroupService,
        private route: ActivatedRoute){

      }
      onSave(){
        console.log('save');
      }

      ngOnInit() {

        // this.idFormation = this.idTraining != null ? this.idTraining : this.route.snapshot.params['id'];
        this.idFormation =  this.idTraining ;

        this.groupSubscription = this.GroupService.groupsSubject.subscribe(
          (groups: any[]) => {
            this.groups = groups;

          }
        );
        this.GroupService.emitGroupsSubject();
        this.onFetch();
      }

      addGroup(){

        if(this.idFormation != null){
          let newGroup : Group= new Group(undefined,"nouveau groupe",this.idFormation,""); 
          this.groups.push(newGroup);
        }
      }

      onFetch() {
        //const id = this.route.snapshot.params['id'];
        this.GroupService.getGroupsFromServer(this.idTraining);

      }

      ngOnDestroy() {

        this.groupSubscription.unsubscribe();

      }
    }

html:

<app-groups *ngFor="let group of groups;let i = index" 
                [groupName]="group.name"
                [groupFormation]="group.training_name"
                [index]="i"
                [idGroup]="group.id"
                [id]="id" 
                >
    </app-groups>

应用程序组是html的简单组成部分。

group.service.ts

@Injectable()
export class GroupService {

  groupsSubject = new Subject<any[]>();

  constructor(private httpClient: HttpClient) { }
  groups : Group[] ;
  getGroupsFromServer(idGroups  : number = null) {
      let url = 'https://XXX.fr/';
      if(idGroups != null){
        url += '/trainings/' + idGroups +"/groups";
      }else{
        url += 'groups/';
      }
      this.httpClient
        .get<any[]>(url)
        .subscribe(
          (response) => {
            this.groups = response;
            this.emitGroupsSubject();
          },
          (error) => {
            console.log('Erreur ! : ' + error);
          }
        );
 }
 emitGroupsSubject(){
      if(this.groups != null)
        this.groupsSubject.next(this.groups.slice());
 }
}

看下面的图片,我写了我想要的东西。 http://puu.sh/CogJM/476c792726.png

希望您能理解我的问题,谢谢您的帮助 托马斯

更新

我尝试了@GérômeGrignon的解决方案

培训:

<mat-accordion>
    <mat-expansion-panel *ngFor="let training of trainings">
        <mat-expansion-panel-header>
            <mat-panel-title>
                {{training.name}}
            </mat-panel-title>
            <mat-panel-description>
              Liste des groupes
            </mat-panel-description>
        </mat-expansion-panel-header>
        <app-group-view
          [idTraining]="training.id"
          [id]="id" 
        ></app-group-view>


    </mat-expansion-panel>
</mat-accordion>

组视图:

 <li class="list-group-item" *ngFor="let group of groups">
          <h4>{{ group.training_name }} groupe {{ group.name }} </h4> 
        </li>

结果:

每次训练我都有相同的小组。如果我转到“网络”选项卡(mozillia控制台),则它对应于上一个ajax请求:http://puu.sh/Coj8v/12a01b2f72.png 谢谢@GérômeGrignon

1 个答案:

答案 0 :(得分:1)

通过删除主题并订阅组件来简化与服务的通信。 然后迭代groups变量。

服务:

getGroupsByTraining(id) {
// ...
return this.httpClient.get(url); }

组视图组件:

groups;
@Input() idTraining: number;

ngOnInit() {
this.service.getGroupsByTraining(idTraining).subscribe(data => this.groups = data); }