程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了如何使用 ngFor 动态生成 HTML 表格。在角度大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决如何使用 ngFor 动态生成 HTML 表格。在角度?

开发过程中遇到如何使用 ngFor 动态生成 HTML 表格。在角度的问题如何解决?下面主要结合日常开发的经验,给出你关于如何使用 ngFor 动态生成 HTML 表格。在角度的解决方法建议,希望对你解决如何使用 ngFor 动态生成 HTML 表格。在角度有所启发或帮助;

我正在尝试动态生成以下 HTML 表,如屏幕截图所示

如何使用 ngFor 动态生成 HTML 表格。在角度

我能够使用虚拟数据手动创建表格,但我的问题是我试图组合多个数据源以实现这种 HTML 表格结构。

有关完整示例,请参见 STACKBLITZ。

数据如下所示(关注活动字段):

    let data = {

ID: '60bf06e6fc8f613117de1db9',activitIEs: {
      '0': ['Power',4,'',2.5,''],'1': ['Attitude',2,3,'2': ['NR',4.5,1.5,'3': ['FMS','4': ['automation','5': ['Path','6': ['Systems','7': ['Environment','8': ['Planning','9': ['Co-ordinate','10': ['Prioritize','11': ['Workload','12': ['Crew','13': ['ATC','14': ['IDentify','15': ['Ass. Risk','16': ['CheckList','17': ['Analysis','']
    }}

活动字段共有 18 个活动。每个都由其 ID 和一系列活动标识。例如'0': ['Power',。 “0”表示活动 Power 的 ID。 4 代表 Attempt1 - Grade & '' 代表 Attempt1 - 注意;等(请参阅屏幕截图以进行说明)。

完整的活动列表存储在不同的变量/文件中,并具有以下结构。

Component.ts

        this.activitIEs = [{
                "ID": 0,"activity": "Power","subject": "Control","icon": "icon-link"
            },{
                "ID": 1,"activity": "Attitude",{...}]
    this.groupedActivitIEs = customGroupByFunction(this.activitIEs,'subject');
this.colors = {Control: '#bfbfbf','AFCS': '#bfbfbf',...}
    this.activitIEsListKey = Object.keys(this.activitIEsList);

下面是我的 HTML 代码。

        <table>
        <caption>Session Summary</caption>
        <tr>
          <th style="wIDth: 40%"></th>
          <th style="wIDth: auto"></th>
          <!-- Loop through AttemptCount variable
            to populate this heading -->
          <th style="wIDth: auto" colspan="2" *ngFor="let attempt of attemptCounts(3)">Attempt {{attempt}}</th>
    
        </tr>
    
        <tr>
          <th style="wIDth: 40%">Subject GrouPing</th>
          <th style="wIDth: auto"></th>
    
          <!-- Populate these heading using the formula
            AttemptCount * 2 (columns - Grade & Note) -->
          <ng-container *ngFor="let attemptLabel of attemptCounts(3)">
    
            <th style="wIDth: auto">Grade</th>
            <th style="wIDth: auto">Note</th>
          </ng-container>
        </tr>
    
        <!-- Loop through all Activity Subjects
        And create heading accordingly. 6 Main Subjects so far -->
    
        <!-- Next Subject -->
    
        <ng-container *ngFor="let ID of activitIEsListKey">
          <tr>
    
            <!-- Generate [rowspan] = (Subject.Array.Length + 1) -->
            <th style="wIDth: 40%;" rowspan="4" [style.background]="colors[ID]">
              {{ID}}</th>
    
            <!-- Loop through each Subject.Array Elements
            and populate -->
          <tr style="wIDth: auto">
            <th>Power</th>
            <td>2.6</td>
            <td>Can Improve</td>
            <td>5.0</td>
            <td>Excellent</td>
            <td>4.5</td>
            <td>Regressed</td>
          </tr>
          <tr style="wIDth: auto">
            <th>Attitude</th>
            <td>4.0</td>
            <td>Fantastic</td>
            <td>4.5</td>
            <td>Getting Better</td>
            <td>5.0</td>
            <td>Nice</td>
          </tr>
          <tr style="wIDth: auto">
            <th>NR</th>
            <td>2.6</td>
            <td>Can Improve</td>
            <td>5.0</td>
            <td>Excellent</td>
            <td>4.5</td>
            <td>Regressed</td>
          </tr>
          <!-- </tr> -->
        </ng-container>
    
      </table>

注意: attemptCounts(n) 只是一个返回 n 个元素数组的函数。例如 attemptCounts(3) 将返回 [0,1,2]

如果要使表格更易于生成,我愿意更改 data.activitIEs 的结构。因此,如果有人有适用于不同数据模型的解决方案,请分享。

“变得更好”、“优秀”的值由教师从表单域中输入。所以它们可以是常数也可以不是。或者甚至只是空字符串。这也能奏效。

有人可以帮我动态生成这张表吗?我已经为此苦苦挣扎了好几天,似乎找不到适合我的解决方案。

所以,请帮助遇险的朋友。

解决方法

一种在不改变数据结构的情况下使其工作的可能方法。

首先是一些接口:

interface Activity {
  id: number;
  activity: string;
  subject: string;
  icon: string;
}

interface Attempt {
  grade: number;
  note: string;
}

interface ActivityAttemp {
  activityName: string;
  attempts: Attempt[];
}

interface ActivitiesBySubject {
  subject: string;
  activities: ActivityAttemp[];
}

data.activities 计算尝试次数:

attemptCounts: number[] = [];

const count =
  ((Object.values(this.data.activities)[0] as string[]).length - 1) / 2;
for (let i = 1; i <= count; ++i) {
  this.attemptCounts.push(i);
}

在将数据提供给 Angular 以对其进行一些预处理之前:

this.subjects.forEach((subject: string) => {
  this.activitiesBySubject.push({
    subject,activities: this.activities
      .filter((act: Activity) => act.subject === subject)
      .map((act: Activity) => {
        return {
          activityName: act.activity,attempts: this.getAttemptsForActivity(act.activity)
        };
      })
  });
});

这个想法是将所有需要的数据放在一个地方,这样 HTML 模板就变得更简单了:

<div style="overflow: auto">
  <table>
    <caption>Session Summary</caption>
    <tr>
      <th style="width: 40%"></th>
      <th style="width: auto"></th>
      <th style="width: auto" colspan="2" *ngFor="let attempt of attemptCounts">Attempt {{attempt}}</th>
    </tr>

    <tr>
      <th style="width: 40%">Subject Grouping</th>
      <th style="width: auto">Activity</th>

      <ng-container *ngFor="let attemptLabel of attemptCounts">
        <th style="width: auto">Grade</th>
        <th style="width: auto">Note</th>
      </ng-container>
    </tr>


    <ng-container *ngFor="let actsBySubj of activitiesBySubject">

      <tr>
        <td [attr.rowspan]="actsBySubj.activities.length + 1">
          {{ actsBySubj.subject }}
        </td>
      </tr>

      <tr *ngFor="let activity of actsBySubj.activities">
        <td>
          {{ activity.activityName }}
        </td>

        <ng-container *ngFor="let attempt of activity.attempts">

          <td>
            {{attempt.grade}}
          </td>
          <td>
            {{attempt.note}}
          </td>

        </ng-container>

      </tr>

    </ng-container>

  </table>
</div>

工作Stackblitz

感谢@GaurangDhorda 的初始 Stackblitz。

更新

要使用下拉菜单,必须将处理移至单独的方法:

  private calcTableData() {
    // reset
    this.attemptCounts = [];
    this.activitiesBySubject = [];

    // find exercise from "selectedExerciseId"
    const selectedExercise = this.data.find(
      (x: any) => x.id === this.selectedExerciseId
    );

    if (!selectedExercise) {
      return; // unable to find exercise
    }

    // calc attempt count eg.: 1,2,3
    for (let i = 1; i <= selectedExercise.attemptCount; ++i) {
      this.attemptCounts.push(i);
    }

    this.subjects.forEach((subject: string) => {
      this.activitiesBySubject.push({
        subject,activities: this.activities
          .filter((act: Activity) => act.subject === subject)
          .map((act: Activity) => {
            return {
              activityName: act.activity,attempts: this.getAttemptsForActivity(
                selectedExercise,act.activity
              )
            };
          })
      });
    });

    console.log(this.activitiesBySubject);
  }

此方法使用成员变量 selectedExerciseId 来获取所选项目。调色板也移至:

  colors: { [key: string]: string } = {
    Control: '#bfbfbf',AFCS: '#fac090','Situational Awareness': '#c4bd97','Leadership / Teamwork': '#d99694',Communication: '#c3d69b','PB. Solving / Decision Making': '#b3a2c7'
  };

事件处理程序 onChange 和生命周期钩子 ngOnit 只调用 calcTableData

  ngOnInit(): void {
    this.calcTableData();
  }

  onChange(e: Event) {
    this.calcTableData();
  }

更新Stackblitz

,

哦,如果你能改变你的数据结构,请这样做。

export interface Attempt {
  grade: number;
  note: string;
}

export interface Activity {
  name: string;
  attempts: Attempt[];
}

// in use
let activities: Activity[] = [
  {
    name: 'Power',attempts: [
      { grade: 3.5,note: 'Could do better' },{ grade: 4.5,note: 'Better' },{ grade: 5,note: 'Passed' },]
  },{
    name: '',// etc…
  }
]

行分组的问题仍然存在,但像这样的结构将更容易管理。

大佬总结

以上是大佬教程为你收集整理的如何使用 ngFor 动态生成 HTML 表格。在角度全部内容,希望文章能够帮你解决如何使用 ngFor 动态生成 HTML 表格。在角度所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: