javascript - 如何在使用 Angular 的 TypeScript 中通过动态键访问 JSON 对象的值
我想访问 JSON 对象中存在的值,并且可以配置用于接收响应的 targetPath。
下面是我的组件类,它将把列表中的数据绑定到 HTML 代码中的自动完成下拉菜单
可配置的键是 'path',我想将其值作为自定义 JSON 对象键 'field' 的键提供。
import { Component, ViewChild } from '@angular/core';
import { MenuItem } from 'primeng/api';
import { SelectItem } from 'primeng/api';
import { SelectItemGroup } from 'primeng/api';
import { FilterService } from 'primeng/api';
import { AutoComplete } from 'primeng/autocomplete';
import { CountryService } from './countryservice';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
providers: [CountryService, FilterService]
})
export class AppComponent {
userDetails: any[];
selectedUserDetails: any[];
selectedValue: any;
selectedUserDetail: any;
path: string = 'contactMedium[0].characteristic.emailAddress';
testVal: string;
constructor() {}
ngOnInit() {
this.userDetails = [
{
id: 'cont-609',
contactMedium: [
{
characteristic: {
emailAddress: '[email '
}
}
]
},
{
id: 'cont-610',
contactMedium: [
{
characteristic: {
emailAddress: '[email '
}
}
]
},
{
id: 'cont-611',
contactMedium: [
{
characteristic: {
emailAddress: '[email '
}
}
]
},
{
id: 'cont-612',
contactMedium: [
{
characteristic: {
emailAddress: '[email '
}
}
]
},
{
id: 'cont-614',
contactMedium: [
{
characteristic: {
emailAddress: '[email '
}
}
]
}
];
}
filterUserDetails(event) {
const filteredNew: any[] = [];
this.getUserDetails().then(response => {
for (let resp of response) {
this.testVal = resp[this.path];
filteredNew.push({
id: resp.id,
field: resp[this.path]
});
}
});
this.selectedUserDetails = filteredNew;
}
getUserDetails(): Promise<any[]> {
return Promise.resolve(this.userDetails);
}
chooseItem(event) {
this.selectedUserDetail =
event.contactMedium[0].characteristic.emailAddress;
}
}
从方法 getUserDetails() 接收到的响应中,我正在构建一个自定义的 JSON 对象数组,包含字段 'id' 和 'field',id 的键是已知的,它本身就是一个 'id',但 field 的键是可配置的,在我的情况下是路径。
但是看起来上面的逻辑在访问键时没有按预期工作,即我没有得到值
filterUserDetails(event) {
const filteredNew: any[] = [];
this.getUserDetails().then(response => {
for (let resp of response) {
this.testVal = resp[this.path];
filteredNew.push({
id: resp.id,
field: resp[this.path]
});
}
});
this.selectedUserDetails = filteredNew;
}
下面是我的 HTML 代码
<h5>Dropdown Testing</h5>
<p>selectedUserDetail : {{selectedUserDetail}}</p>
<p>TestVal : {{testVal}}</p>
<p-autoComplete [(ngModel)]="selectedUserDetail" [suggestions]="selectedUserDetails"
(completeMethod)="filterUserDetails($event)" [dropdown]="true" field="field">
<ng-template let-userDetails pTemplate=" item">
<div>{{userDetails.field}}</div>
</ng-template>
</p-autoComplete>如果我像下面这样更改赋值的使用,一切都能正常工作
字段: resp.contactMedium[0].characteristic.emailAddress
我的代码链接在这里:https://stackblitz.com/edit/primeng-autocomplete-demo-dyihrs?file=src%2Fapp%2Fapp.component.html
这里的期望是将从 getUserDetails() 接收到的 key: contactMedium[0].characteristic.emailAddress 的值分配给在 filterUserDetails() 中构建的自定义 JSON 对象中的 'field' key。
答案#1
你可以使用一个具有动态键的变量
var obj = {
...
}
var key = ...;
obj[key] = somevalue;
或者获取值
var somevalue = obj[key];
答案#2
你应该意识到你的领域可能非常复杂,但在你提到的情况下,可以通过以下方法解决:
resolveField(data: any, field: string): any {
if (data && field) {
let fields: string[] = field.split('.');
let value = data;
for(let i = 0, len = fields.length; i < len; ++i) {
if (value == null) {
return null;
} else {
const pos: number = fields[i].match(/\d+/g)?.[0];
if(pos != null) {
const property = fields[i].match(/^\w+/g);
value = value[property][pos];
} else {
value = value[fields[i]];
}
}
}
return value;
} else {
return null;
}
}
您可以将 resolveField 函数作为逻辑的一部分使用。您可以根据需要或要求对其进行修改,例如:这里仅考虑字母作为属性名称的一部分。
这是你代码的解决方案。
