【问题标题】:Angular PrimeNG Dropdown (groups) - values other than label/valueAngular PrimeNG 下拉列表(组) - 标签/值以外的值
【发布时间】:2021-03-08 19:04:14
【问题描述】:

晚上好,

我一直在使用下拉菜单时遇到问题,尤其是在按组组织时。首先,需要一些时间来了解用于填充下拉列表的选项中的数组需要采用非常特殊的方式。好的,我的 API 现在返回它想要的内容,我可以显示组标题、单个项目,并且可以将所选项目映射到变量。很好,但我只能映射所选项目的标签(或值,我不确定),而我真正想要的是我发送的其他数据。

下面是我的 Angular 组件接收到的 JSON(你会看到我有点困惑并且浪费了一些属性……我不确定 PrimeNG 想要什么,正在努力适应):

[
    {
        "group": null,
        "label": "First group",
        "value": "First group",
        "items": [
            {
                "id": 1,
                "name": null,
                "label": "Par unité",
                "value": "Par unité",
                "description": null
            },
            {
                "id": 2,
                "name": null,
                "label": "Par employé",
                "value": "Par employé",
                "description": null
            }
        ]
    },
    {
        "group": null,
        "label": "Second group",
        "value": "Second group",
        "items": [
            {
                "id": 7,
                "name": null,
                "label": "Temps entre démande et acceptation",
                "value": "Temps entre démande et acceptation",
                "description": null
            },
            {
                "id": 9,
                "name": null,
                "label": "something else",
                "value": "something else",
                "description": null
            }
        ]
    }
]

HTML:

<p-dropdown [options]="clientReports" 
([ngModel])="selectedReport" (onChange)="onReportChange($event)" placeholder="Choose a report" [group]="true">

TS:

clientReports: any[];
selectedReport: any;

onReportChange(event) {
    this.selectedReport = event.value;
    console.log(this.selectedReport);
}

问题和期望的结果:

我认为由于 onChange 调用,我的变量 selectedReport 现在具有所选报告的值(或标签...)(来自 JSON 中的“项目”)。太好了,但是我稍后需要引用该 ID,但我似乎无法弄清楚如何。

需要明确的是,我不希望 id 显示在下拉菜单上,但我需要将该信息传递给 selectedReport(或者,如果我需要第二个变量,我不在乎,我只需要该数据)。

在下拉列表的文档中,我看到有多个属性,例如 optionLabel、optionValue、dataKey 等。其中许多会更改下拉列表中显示的值,其他我似乎看不到它们的作用。

希望有人能帮我解决这个问题。

提前致谢。

【问题讨论】:

    标签: angular drop-down-menu primeng


    【解决方案1】:

    见下文。只要我了解您的需求,我认为这将为您提供所需的东西。

    假设您的数据如下所示:

    sourceData = [
        {
            group: null,
            label: 'First group',
            value: 'First group',
            items: [
                {
                    id: 1,
                    name: null,
                    label: 'Par unité',
                    value: 'Par unité',
                    description: null
                },
                {
                    id: 2,
                    name: null,
                    label: 'Par employé',
                    value: 'Par employé',
                    description: null
                }
            ]
        },
        {
            group: null,
            label: 'Second group',
            value: 'Second group',
            items: [
                {
                    id: 7,
                    name: null,
                    label: 'Temps entre démande et acceptation',
                    value: 'Temps entre démande et acceptation',
                    description: null
                },
                {
                    id: 9,
                    name: null,
                    label: 'something else',
                    value: 'something else',
                    description: null
                }
            ]
        }
    ];
    

    您的组件代码可能如下所示:

    clientReports: SelectItemGroup[] = [];
    selectedReport: any;
    
    ngOnInit(): void {
        this.clientReports = this.sourceData.map(g => {
            return { label: g.label, items: g.items.map(i => ({ label: i.label, value: i })) };
        });
    }
    onReportChange(event: any) {
        this.selectedReport = event.value;
        console.log(this.selectedReport);
    }
    

    真正有趣的部分是将源数据映射到ngOnInit 挂钩中的clientReports 变量。模板中的下拉菜单与您在帖子中的下拉菜单相同。

    <p-dropdown [options]="clientReports"
        ([ngModel])="selectedReport" (onChange)="onReportChange($event)"
        placeholder="Choose a report" [group]="true">
    

    试一试,看看它对你有什么作用。

    【讨论】:

    • 在阅读了这篇文章和 ShayD 的评论之后,我发现你们俩都在同一件事上。正如我意识到的(但还不够远),SelectItem 和 SelectItemGroup 的结构非常特殊,但足以得到我想要的。在您的示例中,如果我理解正确,属性“值”是我可以找到每个项目(selectedReport)的 id 的地方。我会在早上试试这个并报告。谢谢。
    【解决方案2】:

    你应该键入你的对象。这就是 TypeScript 的全部意义所在。 从了解此控件所需的接口开始, 分组模式下的下拉列表期望获得一组 SelectItemGroup 对象。 从primeng源可以看到接口结构:

    export interface SelectItemGroup {
        label: string;
        value?: any;
        items: SelectItem[];
    }
    export interface SelectItem<T = any> {
        label?: string;
        value: T;
        styleClass?: string;
        icon?: string;
        title?: string;
        disabled?: boolean;
    }
    

    假设您的报告界面是:

    export interface ClientReport {
     id:number;
     name:string;
     description:string;
    } 
    

    当您获取数据时,将其映射为:

    [
     {
      label: 'group A',
      value: 1,
      items: [
       { 
        label: 'report 1',
        value: { name: 'report no.1', description: 'first report' } as ClientReport
       } as SelectItem,
       { 
        label: 'report 2',
        value: { name: 'report no.2', description: 'second report' } as ClientReport
       } as SelectItem
      ] as SelectItem[]
     } as SelectItemGroup,
     {
      label: 'group B',
      value: 2,
      items: [
       { 
        label: 'report 3',
        value: { name: 'report no.3', description: 'third report' } as ClientReport
       } as SelectItem,
       { 
        label: 'report 4',
        value: { name: 'report no.4', description: 'fourth report' } as ClientReport
       } as SelectItem
      ] as SelectItem[]
     } as SelectItemGroup
    ] as SelectItemGroup[]
    

    绑定模型将是接口 SelectItem,因此当您记录其值时,您应该会看到您的 ClientReport 对象。

    onReportChange(event) {
        console.log(event.value);
    }
    

    注意不要设置选中的报表,在([ngModel])中定义的时候应该是绑定的

    如果您想在下拉选项中显示自定义信息,您可以使用模板来实现。您可以将 pTemplate 属性设置为“组”、“项目”或/和“选定项目”。例如:

    <ng-template let-group pTemplate="group">
        <div>
            <span>my customized group option:</span> 
            <span>{{group.label}}</span>
        </div>
    </ng-template>
    
    <ng-template let-myItem pTemplate="item">
        <div>
            <span>my customized report item option:</span> 
            <div>{{myItem.value.name}}</div>
        </div>
    </ng-template>
    
    <ng-template pTemplate="selectedItem">
        <div style="color:blue;">
            <div>{{selectedReport?.value?.name}}</div>
        </div>
    </ng-template>
    

    我没有测试代码,所以如果有错别字或任何其他错误,我很抱歉。

    【讨论】:

    • 正如我在上面对理查德的评论所写的那样,这对我了解我是如何偏离轨道有很大帮助。我也在这方面处理对象,我需要使用下拉类的结构,而不是反对它们。我认为看到 Richard 的地图功能和这里布置的界面有很大帮助。是的,我想这就是 Typescript 的乐趣……我需要重新考虑我要发送和处理的对象。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 1970-01-01
    • 2017-06-07
    • 1970-01-01
    相关资源
    最近更新 更多