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

时间:2017-12-14 04:02:22

标签: javascript json angular typescript

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

{
   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上进行映射,那就太酷了

4 个答案:

答案 0 :(得分: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 :(得分: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);

答案 2 :(得分: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>

答案 3 :(得分: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。

EDIT2: 我将为您提供一个更适合您案例的工作示例, 你应该从你的服务器获得一个对象数组,而不仅仅是一个对象,否则你不需要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>