是否有正确的方法将对象键名称映射到更可读的表示形式?

问题描述 投票:2回答:4

我的服务器返回一个如下所示的对象:

{
   firstName: "Joe",
   lastName: "Smith",
   phoneNum: "212-222-2222"
}

我想使用*ngFor在UI(内置Angular 2+)中呈现这个,但我不想像现在这样使用键名。我想要更方便用户的东西,比如

First Name: Joe 
Last Name: Smith 
Phone Number: 212-222-2222

是否有一种“正确”的方式来提供从键名到用户友好键名的映射?如果不是,我可能只是做一些事情来确保键名称为驼峰,然后在UI中,使用函数将驼峰案例键名转换为间隔的用户友好名称。

但如果有人提出的建议不涉及我在服务器端更改任何内容,并在UI上进行映射,那将会很酷

javascript json angular typescript
4个回答
2
投票

公开字段映射器的接口。

interface FieldMapper {
   firstName: string,
   lastName: string,
   phoneNumber: string,
}

interface LabeledField {
  label: string,
  value: string,
}

interface UserRenderable {
  firstname: LabeledField,
  lastname: LabeledField,
  phoneNumber: LabeledField,
}

在您的组件中使用它,例如

@Component({
    ...
    template: `
        <ul>
        <li *ngFor="#user of users">{{user.firstname.label}}
            {{user.firstname.value}}</li>
        <ul>
    `
})
export class Users {
    users: Array<UserRenderable>
    fieldMapper: FieldMapper = {
        firstName: 'First Name',
        lastName: 'Last Name',
        phoneNumber: 'Phone Number'
    }

    constructor(private userService : UserService) {
      const users = userService.get(); 
      this.users = users.map((u) => (
        Object.keys(
          this.fieldMapper
        )
        .reduce(
          (prev, currKey) => {
            prev[currKey] = {
              label: this.fieldMapper[k],
              value: u[k]
            }
            return prev;
          }, {})
      ));
    }

    ngOnInit() {

    }
}

1
投票

您可以将键映射到可读标签,并将响应转换为具有标签/值的对象。

这些对象可以在ngFor中用于显示标签和值。

const response = {
   firstName: "Joe",
   lastName: "Smith",
   phoneNum: "212-222-2222"
};

const labels = {
   firstName: "First Name",
   lastName: "Last Name",
   phoneNum: "Phone Number",
   address: "Address"
}

const result = Object.keys(response).map(key => ({label: labels[key], value: response[key]}));

console.log(result);

1
投票

不,我不会说有正确的方法,因为键可以相当随意。无论如何,如果您有一组固定的键,您可以创建一个映射到用户友好属性键的对象,并在显示逻辑中引用它。

例如:

export class Component {
  friendlyKeys = {
    firstName: "First Name",
    lastName: "Last Name",
    phoneNum: "Phone Number"
  };
}

并从您的模板中引用它

<div *ngFor="property of properties">
  <div>
    {{friendlyKeys[property.key] || property.key}}: {{property.value}}
  </div>
</div>

由于回退逻辑({{|| property.key}})嵌入在视图中,因此上面的代码有点尴尬。如果我们有一个更复杂的策略,例如我们可能想要尝试在几个映射对象中查找并回退到我们基于字母大小写分割键的策略,它将很快变得难以处理。我们可以将逻辑移动到一个函数中,以使视图本身不受逻辑的影响。作为奖励,这使得更容易测试映射行为。

export class Component {
  friendlyKey = friendlyKey;
}

export const friendlyKeys = {
  firstName: "First Name",
  lastName: "Last Name",
  phoneNum: "Phone Number"
};

export function friendlyKey(key: string) {
  return friendlyKeys[key] || key;
}

然后我们将从模板中引用它

<div *ngFor="property of properties">
  <div>
    {{friendlyKey(property.key)}}: {{property.value}}
  </div>
</div>

0
投票

难道你不能使用某种数据绑定,在HTML中使用某种标签吗?我认为关键名称通常不会出现在您的用户界面中,您的代码应该类似于:

<lable>First name</label>{{firstName}}
<lable>Last name</label>{{lastName}}

我可以在答案中编辑代码,为angular2提供一个更实用的例子,但我认为这是做到这一点的方法,所以我不明白为什么你需要有用户友好的密钥名称,因为用户甚至没有看他们。

编辑:我的角度是生锈的,但是从这个链接:dislpalying data in angular我可以看到你应该创建一个模板,你的模板应该包含数据,所以模板应该是这样的:

template: `
<lable>firstName</lable>{{firstName}}
<label>lastName</lable>{{lastName}}
`

等等...

并在模板上使用* ngFor。

编辑2:我将为您提供一个特定于您的案例的更实用的示例,您应该从您的服务器获取一个对象数组,而不仅仅是一个对象,否则您将不需要ngfor,并且您需要迭代对象数组,假设您的数组被称为people,你从api调用得到它:let people = getPeople(),你需要你的模板来创建自定义标签person

<Person *ngFor="let person of people">
  First Name:{{person.firstName}}
  Last Name:{{person.lastName}}
  Number: {{person.number}}
</person>
© www.soinside.com 2019 - 2024. All rights reserved.