【问题标题】:How to group by JSON object using custom Pipes in Angular 2?如何使用 Angular 2 中的自定义管道按 JSON 对象分组?
【发布时间】:2017-10-08 07:25:41
【问题描述】:

我对 Angular 2 还很陌生。那么请有人帮我在 Angular 2 中创建自定义管道吗?

我尝试了以下更改

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({name: 'groupTransactions'})

export class GroupTransactionsPipe implements PipeTransform {
  transform(transactions: Array): Array {

    const grouped = transactions.reduce( (grouping, item) => {
    let month = new Date(item.date).getMonth()+1 ;
      grouping[month] = grouping[month] || [];
      grouping[month].push(
        {
          id: item.id,
          name: item.name, 
          price: item.price
     date: item.date
        }
      );
      return grouping;
    }, {} )
    // 'grouped' is an object with properties keyed on date 
    // and each property value is an array of items

    const result = Object.keys(grouped) 
      .map(key => {
        const val = 
        {
          date: key, 
          items: grouped[key] // can sort here by price or name
        }; 
        return val;
      })
      .sort(function (a, b) {
        return b.date - a.date;
    });
    // Object.keys makes an array
    // so now we have an array of objects 
    // each with a date property and an items property
    // which is an array of objects (as shaped above) 
    // and finally sort on date

    return result
  }
}

但是错误的日期是 1970 年 1 月而不是 2017 年 9 月。目前我们正在按日期分组,但我想要按月分组。简而言之,如果交易放在同一个月的不同日期,它们应该归类在九月份。那么在自定义管道中获取 groupByMoth 需要进行哪些更改。所以我会得到如下输出:

September 17

product 11     £15.00
product 22     £15.00
19 Sep 2017

product 11     £15.00
product 22     £15.00
17 Sep 2017


    August 17

product 11     £15.00
product 22     £15.00
20 Aug 2017

product 11     £15.00
product 22     £15.00
04 Aug 2017


    July 17

product 33     £10.00
product 44     £20.00

    January 16

product 66     £10.00
product 77     £20.00

您能帮忙实现吗?

【问题讨论】:

标签: angular typescript angular2-pipe


【解决方案1】:

这是我认为应该做的工作,不需要外部库

import { Pipe, PipeTransform } from '@angular/core';

@Pipe({name: 'groupTransactions'})
export class GroupTransactionsPipe implements PipeTransform {
  transform(transactions: Array): Array {

    const grouped = transactions.reduce( (grouping, item) => {
      let month = new Date(item.date).getMonth()+1 ;
      grouping[month] = grouping[month] || [];
      grouping[month].push(
        {
          id: item.id,
          name: item.name, 
          price: item.price,
          date: item.date
        }
      );
      return grouping;
    }, {} )
    // 'grouped' is an object with properties keyed on date 
    // and each property value is an array of items

    const monthNames = ["January", "February", "March", "April", "May", 
                        "June", "July", "August", "September", "October",
                        "November", "December"];

    const result = Object.keys(grouped) 
      .map(key => {
        const val = 
        {
          month: key,
          monthName: monthNames[key-1], 
          items: grouped[key] // can sort here by price or name
        }; 
        return val;
      })
      .sort(function (a, b) {
        return b.month - a.month;
    });
    // Object.keys makes an array
    // so now we have an array of objects 
    // each with a date property and an items property
    // which is an array of objects (as shaped above) 
    // and finally sort on date

    return result
  }
}

模板:

<ul>
  <li *ngFor="let dateGroup of transactions | groupTransactions">
    {{ dateGroup.monthName }}
    <ul>
        <li *ngFor="let item of dateGroup.items">
        {{ item.name }} {{ item.price }}
        </li>
    </ul>
  </li>
</ul>

【讨论】:

  • 非常感谢@Richard!这真的很有帮助,但会出现一些错误。我可以得到工作代码示例吗?
  • 没问题。直到大约 10 分钟前,当我更正它时,地图功能中有一个小错误。不能说为什么,但必须添加const val = {...}; return val;
  • 此代码中的错误------const result = Object.keys(grouped) .map(key => { return { date: key, items: grouped[key] // 可以排序这里按价格或名称 }; }) .sort(function (a, b) { return b.date - a.date; });对于日期“检测到无法访问的代码”和项目“找不到名称项目”我可以获得工作代码示例吗?
  • 它现在可以正常工作(请参阅我关于更正的评论)。我让它在 Plunker 中工作,然后 Chrome 说“awe snap”,代码就消失了。但相信我的话......
  • 是的,它现在可以工作了。再次感谢!还有一件事,如果我想按月摸索交易而不是按日期摸索,需要进行哪些更改?
【解决方案2】:

一个简单的解决方案是 lodash groupBy

console.log(_.groupBy([{
    "id": "1",
    "date": 1505408124000,
    "name": "product 11",
    "price": "£15.00"
  },
  {
    "id": "2321",
    "date": 1505408124000,
    "name": "product 112323232",
    "price": "£12325.00"
  },
  {
    "id": "2",
    "date": 1505829312000,
    "name": "product 22",
    "price": "£20.00"
  },
  {
    "id": "3",
    "date": 1505838225000,
    "name": "product 33",
    "price": "£10.00"
  }
],  'date'))
&lt;script src="https://cdn.jsdelivr.net/npm/lodash@4.17.4/lodash.min.js"&gt;&lt;/script&gt;

【讨论】:

  • 谢谢!我想用 Angular 2 自定义管道来实现这一点。
  • 您可以将逻辑放在管道中。 @downvoter 敢评论
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-07
  • 1970-01-01
  • 2016-10-02
  • 2017-10-11
  • 2023-04-03
  • 1970-01-01
相关资源
最近更新 更多