我有一个从api返回的json对象,这是一个示例。
{
"availablePermissions": [
{
"id": 25,
"name": "Dashboard Access",
"systemName": "DashboardAccess"
}, {
"id": 32,
"name": "Claims Access",
"systemName": "ClaimsAccess"
}, {
"id": 34,
"name": "Purchasing Reports Access",
"systemName": "PurchasingReportsAccess"
}
],
"availableApplicationRoles": [
{
"id": "6a8d97b8-7fd5-485c-8eff-5869232b7f26",
"roleName": "Billing",
"systemName": null
}, {
"id": "fbb6c213-2b19-4eec-891f-0552e3b14b5b",
"roleName": "Power User",
"systemName": null
}
],
"allowed": {
"dashboardAccess": {
"144ca9cc-9d56-4cd0-b9b2-c097d606d36e": false,
"fbb6c213-2b19-4eec-891f-0552e3b14b5b": true
},
"claimsAccess": {
"144ca9cc-9d56-4cd0-b9b2-c097d606d36e": false,
"fbb6c213-2b19-4eec-891f-0552e3b14b5b": true
},
"purchasingReportsAccess": {
"144ca9cc-9d56-4cd0-b9b2-c097d606d36e": false,
"fbb6c213-2b19-4eec-891f-0552e3b14b5b": true
}
},
"pager": {
"pageIndex": 0,
"pageSize": 10,
"totalCount": 3,
"totalPages": 1,
"hasPreviousPage": false,
"hasNextPage": false
},
"success": true,
"message": null
}
现在在ngOnInit内部的组件中,我有将其绑定到名为acl的属性的代码,这是代码。
var dummyPermission = {
id: "0",
roleName:"Permission",
systemName:null
}
var self = this;
this.aclData.loadACL(dataTablesParameters, pageInfo)
.subscribe(data => {
if (data.success) {
self.pluginService.lengthMenuAngularDataTable("#ACLTable", dataTablesParameters.length);
self.acl = data;
self.acl.availableApplicationRoles.unshift(dummyPermission);
callback({
recordsTotal: self.acl.pager.totalCount,
recordsFiltered: self.acl.pager.totalCount,
data: []
});
console.log("success load acl table");
self.pluginService.witzThemeLoader(false);
self.pluginService.datePicker();
} else {
self.pluginService.notificationPopup(null, "danger");
self.pluginService.witzThemeLoader(false);
self.pluginService.datePicker();
console.log("error");
}
});
现在在我的html中,我尝试将它们呈现在表中,所以这是引发错误的行的代码。
<tr *ngFor="let pr of acl.availablePermissions">
<td>
<span>{{pr.name}}</span>
</td>
<td *ngFor="let cr of acl.availableApplicationRoles" [hidden]="cr.id == '0'">
<input
attr.data-role-id="{{cr.id}}"
attr.data-permission-name="{{pr.name}}"
attr.data-system-name="{{pr.systemName}}"
[checked]="acl.allowed[pr.systemName][cr.id]"
class="allow allow_{{cr.id}}"
type="checkbox" />
</td>
</tr>
现在,当angular在获取数据后尝试呈现页面时,它似乎陷入了循环,并在控制台中每秒出现以下错误。
ERROR TypeError: Cannot read property '0' of undefined
at Object.eval [as updateRenderer] (ACLComponent.html:85)
at Object.debugUpdateRenderer [as updateRenderer] (core.js:14735)
at checkAndUpdateView (core.js:13849)
at callViewAction (core.js:14195)
at execEmbeddedViewsAction (core.js:14153)
at checkAndUpdateView (core.js:13845)
at callViewAction (core.js:14195)
at execEmbeddedViewsAction (core.js:14153)
at checkAndUpdateView (core.js:13845)
at callViewAction (core.js:14195)
现在第85行是我在上面提供的html。
<td *ngFor="let cr of acl.availableApplicationRoles" [hidden]="cr.id == '0'">
我只是不知道出了什么问题,我查看了看起来都还不错的数据,我只是不知道为什么会这样,有人可以解释吗?
#更新
经过一些调试后,我得以深入了解问题所在,就在这里。
在我共享的api响应数据对象中,有一个名为“允许”的对象,这是格式。
"allowed": {
"dashboardAccess": {
"144ca9cc-9d56-4cd0-b9b2-c097d606d36e": false,
"fbb6c213-2b19-4eec-891f-0552e3b14b5b": true
},
"claimsAccess": {
"144ca9cc-9d56-4cd0-b9b2-c097d606d36e": false,
"fbb6c213-2b19-4eec-891f-0552e3b14b5b": true
},
"purchasingReportsAccess": {
"144ca9cc-9d56-4cd0-b9b2-c097d606d36e": false,
"fbb6c213-2b19-4eec-891f-0552e3b14b5b": true
}
}
现在在html中,我有这行。
[checked]="acl.allowed[pr.systemName][cr.id]"
现在这需要从上面允许的对象中过滤出一个与systemName匹配的对象,然后过滤出一个与id匹配的对象,问题是,它不是数组,所以返回为undefined。
我不确定如何处理此类对象,我们将不胜感激。
答案 0 :(得分:1)
您将td隐藏在cr.id =='0'
<td *ngFor="let cr of acl.availableApplicationRoles" [hidden]="cr.id == '0'">
虽然它确实隐藏了,但仍会创建td元素,并且语句将执行,但您的操作却出现了错误:
[checked]="acl.allowed[pr?.systemName][cr.id]"
因为在这种情况下cr.id为0:
[checked]="acl.allowed[pr?.systemName][0]"
您需要添加条件或对容器使用* ngIf。
答案 1 :(得分:0)
您可以使用optional chaining,这应该可以解决问题
<!-- notice the ? after acl and cr -->
<td *ngFor="let cr of acl?.availableApplicationRoles" [hidden]="cr?.id == '0'">
基本上,所发生的是angular试图在返回数据之前呈现列表,以使其保持循环并抛出错误。如果将?
放在acl
后,将跳过*ngFor
,直到返回数据
编辑
您需要像这样在所有引用cr上使用?
<tr *ngFor="let pr of acl?.availablePermissions">
<td>
<span>{{pr?.name}}</span>
</td>
<td *ngFor="let cr of acl?.availableApplicationRoles" [hidden]="cr?.id == '0'">
<input
attr.data-role-id="{{cr?.id}}"
attr.data-permission-name="{{pr?.name}}"
attr.data-system-name="{{pr?.systemName}}"
[checked]="acl.allowed[pr?.systemName][cr.id]"
class="allow allow_{{cr?.id}}"
type="checkbox" />
</td>
</tr>
答案 2 :(得分:-1)
好的,所以我终于可以使用以下代码使它正常工作。
<tr *ngFor="let pr of acl.availablePermissions let i = index">
<td scope="col">
<span>{{pr.name}}</span>
</td>
<td *ngFor="let cb of aclPermissions[i].cb">
<input attr.data-role-id="{{cb?.roleId}}"
attr.data-permission-name="{{pr?.permissionName}}"
attr.data-system-name="{{cb?.systemName}}"
class="allow allow_{{cb?.roleId}}"
type="checkbox"
[checked]="cb?.isChecked" />
</td>
如您所见,我现在正在使用索引,这有助于我循环到对象数组。
感谢大家的帮助。