【问题标题】:Is it possible to dynamically populate Angular 2 Material Tabs with a For Loop Subscribe?是否可以使用 For 循环订阅动态填充 Angular 2 材质选项卡?
【发布时间】:2018-05-20 02:20:24
【问题描述】:

我需要使用 For 循环在 Angular 2 站点上填充动态数量的选项卡,该循环使用订阅从数据库服务获取数据,我想知道这是否可能。

我的数据集按类细分:A、B 和 C,它们每个都有一个子类 1 和 2。所以我想让我的结果动态创建 3 个选项卡(选项卡 A、选项卡 B 和选项卡 C)。到目前为止,我已经完成了这项工作。

然后我需要这些选项卡中的每一个来显示其子类的数据。截至目前,循环运行了 3 次并提供了所需的数据,但每一页只显示 C 类的数据,因为它是最后一个运行的,并且模型已更新其所有数据。

以下是我目前所拥有的。

classdata.component.html

<mat-tab-group>
<mat-tab *ngFor="let classresult of classresults;" label="Class -{{classresult.Class_Name}}">
<table class ="responstable">
<thead>
<tr>
<th>Sub-Class Name</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let subclassresult of subclassresults;">
<td>{{subclassresult.Sub_Class_Name}}  </td>
<td>{{subclassresult.Value}}  </td>
</tr>
</tbody>
</table>
</mat-tab>
</mat-tab-group>

classdata.component.ts

   // Populate Class Level Data
   this.databaseService.getClass()
   .subscribe(classresults => this.classresults = classresults,
    error => console.log('ERROR!'),
    // Populate Sub-Class Level Data
    () => { for (const classresult of this.classresults) {
      this.selectedClassId = classresult.Class_ID;
      console.log(this.selectedClassId);
      this.databaseService.getSubClass(this.selectedClassId)
      .subscribe(subclassresults => this.subclassresults = subclassresults);
    }
  }
  );

database.service.ts

getClass(): Observable<ClassResult[]> {
  const url = 'http://localhost:3000/c';
  const data = ({
  });
  return this._http.post(url, data)
  .pipe(
    map((res) => {
      console.log(res);
      return <ClassResult[]> res;
    })
  );
}


getSubClass(Class_ID): Observable<SubClassResult[]> {
  const url = 'http://localhost:3000/sc';
  const data = ({
    classid: Class_ID
  });
  return this._http.post(url, data)
  .pipe(
    map((res) => {
      console.log(res);
      return <SubClassResult[]> res;
    })
  );
}

【问题讨论】:

    标签: html angular for-loop tabs angular-material


    【解决方案1】:

    您正在为每个父类获取每个子类,但您正在将每个结果重新分配给类变量this.subclassresults。基本上,您正在用当前结果覆盖每个先前的结果。这就是为什么每个页面都只显示 C 类的数据。

    有许多不同的解决方案可以解决这个问题。

    解决方案可能是您使用 forkJoin Observable 并将您的 parentClass 的结果及其子类保存在自己的对象中:

    this.databaseService.getClass().pipe(
      switchMap(classResults => {
        const subClassRequests = classResults.map(
          classResult => this.dabaseService
            .getSubClass(classResult)
            .pipe(map(subClassResults => {classResult, subClassResults}))
           )
           return forkJoin(subClassRequests)
      })
    ).subscribe(results => this.results = results);

    results 将您的数据保存为一个数组。

    并在您的模板中像这样使用它:

    <mat-tab-group>
      <mat-tab *ngFor="let result of results;" label="Class -{{result.classresult.Class_Name}}">
        <table class ="responstable">
          <thead>
            <tr>
              <th>Sub-Class Name</th>
              <th>Value</th>
            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let subclassresult of result.subclassresults;">
              <td>{{subclassresult.Sub_Class_Name}}  </td>
              <td>{{subclassresult.Value}}  </td>
            </tr>
          </tbody>
        </table>
      </mat-tab>
    </mat-tab-group>

    我实现了一个小的工作演示: StackBlitz Demo

    【讨论】:

    • 感谢您抽出宝贵时间整理这些内容。我正在尝试实施它,但遇到了一些问题。我的 getClass 和 getSubClass 都需要如下变量: getClass(x, x, x) 和 getSubClass(classid, x, x, x) 这些变量被传递到数据库以在各自的查询中使用。这会引起并发症吗?很抱歉没有包括在我的 OP 中,但我认为它们不会引起问题。
    • 这应该没问题。您面临哪些问题?
    • 我的 linter 显示如下: '(subclassreslts: Observable) => void' 类型的参数不可分配给 'UnaryFunction 类型的参数,可观察的>'。类型 'void' 不可分配给类型 'Observable'。 [ts] 逗号运算符左侧未使用,没有副作用。
    • 我更新了我的答案。我在 databaseService.getSubClasses() 忘记了地图运算符
    • 感谢您回复我 - 我现在收到以下错误: ts(101,49): error TS2695: 逗号运算符的左侧未使用且没有副作用。错误 TS2339:“ClassDataComponent”类型上不存在属性“结果”。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-07
    • 1970-01-01
    • 2013-10-31
    • 1970-01-01
    相关资源
    最近更新 更多