【问题标题】:How can I add an empty row in a for loop based on a previous for loop?如何根据前一个 for 循环在 for 循环中添加一个空行?
【发布时间】:2020-02-18 11:54:29
【问题描述】:

我正在尝试制作一个显示两个时间段销售额的比较报告,在这种情况下,我选择了 10 月 1 日至 31 日和 11 月 1 日至 30 日。我从同一个 Json 文件加载数据,但作为两个单独的查询,第一个使用 10 月期间,第二个使用 11 月期间。

这是我目前拥有的代码:

// October 1-31
<div class="col-6" *ngFor="let periods of reportData">
    <div *ngFor="let reportVal of periods.groupedTransactions">
        <div class="row" *ngIf="reportData.length > 0">
            <div class="col-12">
                <h6>Customer: {{reportVal.name}}</h6>
            </div>
            <div class="col">
                <h6>Total Sales: {{reportVal.totalSales | number}}</h6>
            </div>
        </div>
    </div>
</div>
// November 1-30
<div class="col-6" *ngFor="let comPeriods of comReportData">
    <div *ngFor="let reportVal of comPeriods.groupedTransactions">
        <div class="row" *ngIf="comReportData.length > 0">
            <div class="col-12">
                <h6>Customer: {{reportVal.name}}</h6>
            </div>
            <div class="col">
                <h6>Total Sales: {{reportVal.totalSales | number}}</h6>
            </div>
        </div>
    </div>
</div>

结果如下:

如果该客户没有销售,有没有办法添加一个函数,该函数将在 11 月添加一个空行?我想让所有客户垂直对齐。

因为 for 循环的周期是基于选定的日期,所以将列放在同一个循环中只会获取一个日期的数据。

如果有人可以帮助我或告诉我在哪里可以解决这个问题,我们将不胜感激!

【问题讨论】:

    标签: javascript html angular loops for-loop


    【解决方案1】:

    无论您采用何种方法,您的主要循环都应该针对所有时期的客户集。

    我将创建一个结合客户和报告的非规范化视图模型。您最终的视图模型结构在本质上可能看起来像这样:

    periods: [
      {
        name: 'October 2019'
        customers: [
          {
            name: 'John',
            totalSales: 100
          },
          ...
        ]
      }
    ]
    

    复杂性在于您如何构建它。类似的东西

    periods.forEach(period => {
      const periodViewModel = {};
      this.viewModel.periods.push(periodViewModel);
    
      customers.forEach(customer => {
        const customerViewModel = {
          name: customer.name,
          totalSales: this.getSales(customer, period)
        };
    
        periodViewModel.customers.push(customerViewModel);
      });
    });
    

    this.getSales(customer, period) 是获取给定客户和期间的销售数据的某种方式——可能是一个局部变量。您可能希望优化您的销售数据,以便按客户/期间检索,具体取决于您拥有多少期间/客户。

    然后将这个视图模型绑定到您的 HTML 变得非常简单。让您的 typescript 处理复杂的模型,并让您的 UI 保持简单。

    【讨论】:

    • 所以现在我正在从包含所有交易和客户名称的 Json 文件中提取数据,因此所有内容都合并到同一个文件中。它在此期间吸引所有客户和交易。我应该以某种方式吸引客户,然后是两个交易期吗?对不起,如果我误解了你。
    • 将那个json块转换成你想要的结构应该是相当简单的。在处理 json 时,提取相关数据。我会将活跃客户存储在Map&lt;Customer&gt; 中以获取您的客户群。我的示例假设现有的客户和期间数组,但这不会改变答案的原则。您能否创建一个堆栈闪电战(使用匿名或简化数据)向我展示您目前拥有的内容。
    • 这是带有报告部分的堆栈闪电战。我无法获取 json 文件以在演示中提取数据,但两个 json 句点包含在 assets 文件夹中。希望您能够发现我需要更改以对齐期间。 stackblitz.com/edit/…
    • 这是一个小针头的大海捞针!你能用最少的代码和静态模型而不是 json 数据重现问题吗?
    【解决方案2】:

    希望对您有所帮助...如果这不是您想要显示的预期结果,请分享 json 格式。

    customer.component.html

    <div class="container">
    <h2>Customer Sales</h2>
    <p>The below table is listing monthly sales of the customer in the year 2019 </p>  
    <div *ngFor="let report of reportData">
        <h5>Month: {{report.month}}</h5>
        <table class="table">
            <thead>
                <tr>
                    <th>Customer</th>
                    <th>Total Sales</th>
                </tr>
            </thead>
            <tbody>
                <tr *ngFor="let sales of report.groupedTransactions">
                    <td>{{sales.name}}</td>
                    <td>{{sales.totalSales}}</td>
                </tr>
            </tbody>
        </table> 
    </div>
    

    customer.component.ts

    ngOnInit() {
    
    
    this.reportData = [
      {
        month: 'October',
        groupedTransactions: [
          {
            name: 'John',
            totalSales: 100
          },
          {
            name: 'Rita',
            totalSales: 80
          },
          {
            name: 'Edward',
            totalSales: 70
          },
        ]
      },
      {
        month: 'November',
        groupedTransactions: [
          {
            name: 'John',
            totalSales: 90
          },
          {
            name: 'Rita',
            totalSales: null
          },
          {
            name: 'Edward',
            totalSales: 120
          },
        ]
      }
    ]
    

    }

    } }

    【讨论】:

      【解决方案3】:

      一种解决方案是对齐两个时期。例如,添加一个缺少客户的名称和总销售额为 0 的条目。我不知道您的 json 喜欢什么,但也许您还应该假设不同时期的客户顺序可能不一样。按名称排序可能是一种解决方案。

      你可以想出这样的东西来对齐两个时期:

      interface CustomerReport {
        name: string;
        totalSales: number;
      }
      
      alignPeriods(firstPeriod: CustomerReport[], secondPeriod: CustomerReport[]) {
          const alignedFirstPeriod: CustomerReport[] = Object.assign([], firstPeriod);
          const alignedSecondPeriod: CustomerReport[] = [];
      
          firstPeriod.forEach(customer => {
            const secondCustomer = secondPeriod.find(secCustomer => secCustomer.name === customer.name);
            if (!secondCustomer) {
              alignedSecondPeriod.push({name: customer.name, totalSales: 0});
            } else {
              alignedSecondPeriod.push(secondCustomer);
            }
          });
      
          secondPeriod.forEach(customer => {
            const firstCustomer = firstPeriod.find(fstCustomer => fstCustomer.name === customer.name);
            if (!firstCustomer) {
              alignedFirstPeriod.push({name: customer.name, totalSales: 0});
              alignedSecondPeriod.push(customer);
            }
          });
      
          const alignedCustomers = [alignedFirstPeriod, alignedSecondPeriod];
          return alignedCustomers;
        }
      

      此函数确保两个数组的顺序相同,并为所有不在其他期间的客户添加一个带有 totalSales:0 的新条目。这假设您的客户的姓名是唯一的 ID。

      现在您可以遍历模板中的两个对齐数组。

      这可行,但它不是一个干净的解决方案,您应该考虑像 Kurt Hamilton 在他的回答中提到的那样更改您的数据模型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-04
        • 1970-01-01
        • 2014-12-12
        • 1970-01-01
        • 2014-03-21
        • 2015-01-29
        • 2018-08-23
        • 1970-01-01
        相关资源
        最近更新 更多