创建使用 Underscore.js groupBy 计算的敲除并为 select 控件映射

Create knockout computed with Underscore.js groupBy & map for select control

我正在尝试创建一个局部视图,该视图将显示带有分组选项的 select 控件。

我有一个初始位 JSON:

[{
    "customFrequencyId": 1008,
    "startDate": "2016-10-29T00:00:00Z",
    "endDate": "2016-11-25T00:00:00Z",
    "label": "P11 2016"
}, {
    "customFrequencyId": 1008,
    "startDate": "2016-11-26T00:00:00Z",
    "endDate": "2016-12-31T00:00:00Z",
    "label": "P12 2016"
}, {
    "customFrequencyId": 1008,
    "startDate": "2017-01-01T00:00:00Z",
    "endDate": "2017-01-28T00:00:00Z",
    "label": "P1 2017"
}, {
    "customFrequencyId": 1008,
    "startDate": "2017-01-29T00:00:00Z",
    "endDate": "2017-02-25T00:00:00Z",
    "label": "P2 2017"
}, {
    "customFrequencyId": 1008,
    "startDate": "2017-02-26T00:00:00Z",
    "endDate": "2017-03-23T00:00:00Z",
    "label": "P3 2017"
}]

我当前的 TypeScript:

export class CustomPeriodSelection {

    customPeriods: KnockoutObservable<any[]> = ko.observable([]);
    selectedOption: KnockoutObservable<any> = ko.observable();

    customGroups: KnockoutComputed<any[]> = ko.computed(() => {
        var groupedList = _.groupBy(this.customPeriods(), function (item: any) {
            return item.endDate.substring(0, 4);
        });

        return _.map(groupedList, function (item: any) {
            return item;
        });
    });

    constructor(
        customPeriods: any[]
    ) {
        this.customPeriods(customPeriods);
    }
}

我的意图是从 Knockout 计算中得到以下 JSON...

[{
    "label": 2016,
    "customPeriods": [{
        "customFrequencyId": 1008,
        "startDate": "2016-10-29T00:00:00Z",
        "endDate": "2016-11-25T00:00:00Z",
        "label": "P11 2016"
    }, {
        "customFrequencyId": 1008,
        "startDate": "2016-11-26T00:00:00Z",
        "endDate": "2016-12-31T00:00:00Z",
        "label": "P12 2016"
    }]
}, {
    "label": 2017,
    "customPeriods": [{
        "customFrequencyId": 1008,
        "startDate": "2017-01-01T00:00:00Z",
        "endDate": "2017-01-28T00:00:00Z",
        "label": "P1 2017"
    }, {
        "customFrequencyId": 1008,
        "startDate": "2017-01-29T00:00:00Z",
        "endDate": "2017-02-25T00:00:00Z",
        "label": "P2 2017"
    }, {
        "customFrequencyId": 1008,
        "startDate": "2017-02-26T00:00:00Z",
        "endDate": "2017-03-23T00:00:00Z",
        "label": "P3 2017"
    }]
}]

然后将像这样放入 select 控件..

<select class="form-control" data-bind="foreach: customGroups, event: { change: periodChanged }">
    <optgroup data-bind="attr: { label: $data.label}, foreach: customPeriods">
        <option data-bind="text: $data.label, value: $data"></option>
    </optgroup>
</select>

我假设是 groupBy 和 map 的实现不正确。如何按年份对 customPeriods 数组进行分组,然后将结果映射到具有上述所需结构的新数组?

我目前从我编写的代码中得到以下内容。

[
  [
    {
      "customFrequencyId": 1008,
      "startDate": "2016-10-29T00:00:00Z",
      "endDate": "2016-11-25T00:00:00Z",
      "label": "P11 2016"
    },
    {
      "customFrequencyId": 1008,
      "startDate": "2016-11-26T00:00:00Z",
      "endDate": "2016-12-31T00:00:00Z",
      "label": "P12 2016"
    }
  ],
  [
    {
      "customFrequencyId": 1008,
      "startDate": "2017-01-01T00:00:00Z",
      "endDate": "2017-01-28T00:00:00Z",
      "label": "P1 2017"
    },
    {
      "customFrequencyId": 1008,
      "startDate": "2017-01-29T00:00:00Z",
      "endDate": "2017-02-25T00:00:00Z",
      "label": "P2 2017"
    },
    {
      "customFrequencyId": 1008,
      "startDate": "2017-02-26T00:00:00Z",
      "endDate": "2017-03-23T00:00:00Z",
      "label": "P3 2017"
    }
  ]
]

我已经阅读了其他问题,但我正在苦苦挣扎。任何帮助将不胜感激(如果可能,请提供解释,而不是仅仅为我做这件事)。谢谢!

你很接近。

变化:

return _.map(groupedList, function (item: any) {
            return item;
        });

return _.map(groupedList, function (item: any) {
            return { label: item[0].endDate.substring(0, 4), customPeriods: item };
        });

虽然我想先在 plunker 中验证这一点。