简体   繁体   中英

Angular: linking data to dynamic table using *ngFor

I am creating a dynamic table. The problem with my json structure below is that the Students object does not contain Subjects array within the object, but rather Students[] and Subjects[] are defined through Links[], where there is link defined for student a subject.

The output of the table should look like this: 在此处输入图像描述

Do you have any suggestions how to create *ngFor in ??? area that links each student to its subjects?

The json structure looks like this:

export class StudentsAndSubjects {
 info: SchoolInformation;
}

export class SchoolInformation {
 students: Students[];
 subjects: Subjects[];
 links: Links[];
}

export class Students {
 id: string;   //example: student_1
 name: string;
 surname: string;
};
export class Subjects{
 id: string;   //example: subject_1
 name: string;
};
export class Links{
 studentId: string; //example: student_1
 subjectId: string; //example: subject_1
};

The table structure:

@Component({
 selector: 'app-student-and-subjects',
 template: `
   <table>
     <tr *ngFor="let row of rowHeaders">
        <td *ngFor="let item of data.info.students.name">
           <span *ngIf="row !== 'Subjects'">{{ item[row] }}</span>
        </td>
        <table *ngIf="row === 'Subjects'">
            <tr **???**>
               <td>{{ subject}}</td>
            </tr>
        </table>
     </tr>
   </table>
`;
})
export class StudentsAndSubjects {
 @Input() data: StudentSubjectData;
 readonly rowHeaders = ['Student','Subjects']
}

First, I think you need to restructure your table a bit. Since the table of subjects is associated to a particular student, it should probably live inside the td that contains that student's data:

<table>
  <tr *ngFor="let row of rowHeaders">
    <td *ngFor="let student of data.info.students"> <--- each td contains data for a student
      <span *ngIf="row !== 'Subjects'">{{ student.name }}</span>

      <table *ngIf="row === 'Subjects'"> <--- move this table inside the td
        <tr>
          <td *ngFor="let subject of getSubjectsForStudent(student)"> <-- the *ngFor you were missing
            {{ subject.name }}
          </td>
        </tr>
      </table>
    </td>
  </tr>
</table>

Also note that I changed your *ngFor="let item of data.info.students.name" so it iterates over data.info.students rather than data.info.students.name since you need the student instance data (and data.info.students.name isn't a collection).

And to display the student name, I replaced {{ item[row] }} with {{ student.name }} .

Then, to display the subjects for that student, you would need to create a method that accepts the student object (or just its id ) and then parses the data and returns the student's associated subjects.

That method is what you would need in the missing *ngFor that you're asking about.

(Alternatively, of course, you could transform the data ahead of time into a mapping object that maps the students to their subjects.)

So the missing *ngFor that you're asking about would look something like this:

<td *ngFor="let subject of getSubjectsForStudent(student)">

Note that it's on the td , not the tr like in your markup. That's because each subject has its own cell, not its own row—all subjects are in the same row.

Here's a StackBlitz showing this approach.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM