【问题标题】:Sorting a reactive form array对反应式表单数组进行排序
【发布时间】:2018-02-12 14:04:19
【问题描述】:

我已经成功构建了一个响应式表单,但我希望使用自定义管道对结果进行排序:

<tr *ngFor="let record of myForm.controls.openingHoursForm.controls | sort: 'When'; let c=index; let first = first; let last = last;" [formGroupName]="c">
                        <td><input type="text" formControlName="Heading" class="openingTimesField" /></td>
                        <td><input type="text" formControlName="Subheading" class="openingTimesField" /></td>
                        <td><input type="text" formControlName="When" class="openingTimesField" /></td>
                        <td><input type="text" formControlName="Times" class="openingTimesField" /></td>
                        <td><input type="text" formControlName="Emphasis" class="openingTimesField" /></td>
    </tr>

我的自定义管道如下所示:

import { Pipe } from "@angular/core";

@Pipe({
    name: "sort"
})
export class ArraySortPipe {
    transform(array: Array<string>, args: string): Array<string> {
        if (array !== undefined) {
            console.log(array);
            array.sort((a: any, b: any) => {
                if (a[args] < b[args]) {
                    return -1;
                } else if (a[args] > b[args]) {
                    return 1;
                } else {
                    return 0;
                }
            });
        }
        return array;
    }
}

但这似乎不起作用。我知道反应形式数组结构与基本数组不同,因为它有一个嵌套的“控件”对象。有什么想法可以解决这个问题吗?

更新: 此处的表单设置也可供参考:

this.myForm = this.fBuilder.group({
            openingHoursForm: this.fBuilder.array([])
        });

this.openingHoursArray.forEach(element => {

                    (<FormArray>this.myForm.get('openingHoursForm')).push(this.fBuilder.group({
                            Id: [element.Id],
                            Heading: [element.Heading],
                            Subheading: [element.Subheading],
                            When: [element.When],
                            Times: [element.Times],
                            Emphasis: [element.Emphasis],
                            SortOrder: [element.SortOrder]
                    }));                  

                });

【问题讨论】:

    标签: angular


    【解决方案1】:

    编辑:Add stackblitz POC

    由于您将 FormGroup 数组传递给管道,因此您必须通过 a.controls[args].value; 访问值;

        @Pipe({
            name: "sort",
            pure: false
        })
        export class ArraySortPipe {
            transform(array: Array<string>, args: string): Array<string> {
                if (array !== undefined) {
                    return array.sort((a: any, b: any) => {
    
                        const aValue = a.controls[args].value;
                        const bValue = b.controls[args].value;
    
                        if (aValue < bValue) {
                            return -1;
                        } else if (aValue > bValue) {
                            return 1;
                        } else {
                            return 0;
                        }
                    });
                }
                return array;
            }
        }
    

    WATCHOUT:@Pipe 装饰器中的纯 FALSE。有了这个,即使输入参考没有改变,管道也会被重新评估。 (尝试更改 stackblitz 中的 when 值,该行将重新排序)

    注意:如果您不想在输入更改时即时使用,则应该在表单实例化中进行排序,而不是使用在每次更改检测时都会“重新触发”的管道。

    【讨论】:

    • 不抱歉,这不起作用。除非 a 和 b 是要排序的实际值,否则它不会深入到 array.sort 中。
    • 抱歉还是不行。如果我放一个 console.log(a);在 array.sort((a: any, b: any) => { 没有打印出来。
    • 好的,这次在 stackblitz 上检查一下,抱歉之前的两个未检查的答案。
    • 非常感谢,我明天回到电脑前试试看:) 这对整数排序有用吗?
    • 是的,在示例中我使用了整数。但是你可以对 Date 进行排序(因为 Date 对象是原生可排序的)或任何你想要的,只要你提供好的自定义排序功能
    猜你喜欢
    • 2022-01-06
    • 2022-12-29
    • 1970-01-01
    • 1970-01-01
    • 2021-11-25
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    相关资源
    最近更新 更多