0

我在使用来自 API 调用的数据时遇到问题:我想使用检索到的数据来设置复选框中的选中状态,但是组件在 api 响应之前被初始化并且我得到了一些控制台错误:

错误类型错误:无法读取未定义的属性“id”

我也用解析器测试了行为,但我遇到了同样的问题,即使在初始化之前记录了响应数组:

组件.ts

...
export class RolesComponent implements OnInit {

  flag: boolean = false;
  simpleArr: object[] = [
    { userId: 1, id: 2 },
    { userId: 1, id: 3 },
    { userId: 1, id: 5 },
    { userId: 1, id: 7 }
  ]
  permArr: object[] = [];
  permArrResolved: object[] = [];

  levels = [
    { name: 0, description: 'Creazione nuovo utente' },
    { name: 1, description: 'Reset password di qualsiasi utente' },
    { name: 2, description: 'Eliminazione di qualsiasi utente' },
    { name: 3, description: 'Modifica livello di qualsiasi utente' },
    { name: 4, description: 'Rinnovo delle licenze' },
    { name: 5, description: 'Gestione completa delle licenze' },
    { name: 6, description: 'Gestione completa dei clienti' },
    { name: 7, description: 'Gestione completa dei PC' }
  ];

  constructor(private api: RolesApiService, private route: ActivatedRoute, ) {

    this.api.getKeys().subscribe(keys => {
      this.permArr = keys;
      console.log(this.permArr);
      this.flag = true
    });

    this.route.data.pipe(
      map(data => data.cres)).subscribe((key) => {
        this.permArrResolved = key;
        console.log(this.permArrResolved);
      });

  }

  ngOnInit() {
    console.log('component is initialized');
  }

}

组件.html

<form *ngIf="flag">
  <h2>with permArr[0].id</h2>
  <ng-container *ngFor="let level of levels">
    <input type="checkbox" [checked]="level.name === permArr[0]?.id" />{{level.name}} - {{level.description}}
    <br>
  </ng-container>

<hr>

<h2>with simpleArr[level.name].id</h2>
  <ng-container *ngFor="let level of levels">
    <input type="checkbox" [checked]="level.name === simpleArr[level.name]?.id" />{{level.name}} - {{level.description}}
    <br>
  </ng-container>

<hr>

  <h2>with permArr[level.name].id</h2>
  <ng-container *ngFor="let level of levels">
    <input type="checkbox" [checked]="level.name == permArr[level.name]?.id" />{{level.name}} - {{level.description}}
    <br>
  </ng-container>

<hr>

  <h2>with permArr[level.name].id using resolver</h2>
  <ng-container *ngFor="let level of levels">
    <input type="checkbox" [checked]="level.name == permArrResolved[level.name]?.id" />{{level.name}} - {{level.description}}
    <br>
  </ng-container>

</form>

我制作了一个 stackblitz 演示来展示我使用的错误、api 服务、路由和解析器。在这里:https ://stackblitz.com/edit/async-angular-resolver

我怎么解决这个问题?

编辑:使用安全操作符不能解决错误 EDIT2:在表单标签中使用 *ngIf 不能解决错误

4

4 回答 4

3

这里已经有几个答案可以正确回答您提出的问题 - 它们不适合您的原因是因为您绑定的数据与您的 id 不匹配。

您之前的问题基本上都在问同样的事情:

为了防止社区进一步浪费精力,我已经开始编写您应该自己编写的调试代码。这显示了安全导航操作员如何修复模板问题,正如一些人已经建议的那样 - 包装*ngIf也可以解决问题,我添加的值显示了为什么您的复选框未被选中。

https://stackblitz.com/edit/async-angular-resolver-hxxyw4?file=src/app/roles/roles.component.html

于 2018-08-02T09:59:06.570 回答
2

您可以使用安全导航运算符?.

Angular 安全导航运算符 (?.) 是防止属性路径中出现空值和未定义值的一种流畅且方便的方法。

例如:

[checked]="level.name === permArr[0]?.id"

这基本上等同于permArr[0] && permArr[0].id

于 2018-08-02T09:09:11.207 回答
1

使用响应后加载视图*ngIf

<form *ngIf="flagpermArr && flagpermpermArrResolved">
    <h2>with permArr[0].id</h2>

    <ng-container *ngFor="let level of levels">
        <input type="checkbox" [checked]="level.name === permArr[0]?.id" />{{level.name}} - {{level.description}}
        <br>
    </ng-container>
    <hr>
    <h2>with simpleArr[level.name].id</h2>

    <ng-container *ngFor="let level of levels ; let i = index">

 <!-- <input *ngIf="" type="checkbox" [checked]="level.name === simpleArr[level.name].id" />{{level.name}} - {{level.description}} 
    -->
        <br>
    </ng-container> 
    <hr>
    <h2>with permArr[level.name].id</h2>
    <ng-container *ngFor="let level of levels">
        <input type="checkbox" [checked]="level.name == permArr[level.name]?.id" />{{level.name}} - {{level.description}}
        <br>
    </ng-container>
    <hr>
    <h2>with permArr[level.name].id using resolver</h2>
    <ng-container *ngFor="let level of levels">
        <input type="checkbox" [checked]="level.name == permArrResolved[level.name]?.id" />{{level.name}} - {{level.description}}
        <br>
    </ng-container>
</form>

TS:

 export class RolesComponent implements OnInit {

  flagpermArr: boolean = false;
  flagpermpermArrResolved: boolean = false;

  simpleArr: object[] = [
    { userId: 1, id: 1 },
    { userId: 1, id: 2 },
    { userId: 1, id: 5 },
    { userId: 1, id: 7 }
  ]
  permArr: object[] = [];
  permArrResolved: object[] = [];

  levels = [
    { name: 0, description: 'Creazione nuovo utente' },
    { name: 1, description: 'Reset password di qualsiasi utente' },
    { name: 2, description: 'Eliminazione di qualsiasi utente' },
    { name: 3, description: 'Modifica livello di qualsiasi utente' },
    { name: 4, description: 'Rinnovo delle licenze' },
    { name: 5, description: 'Gestione completa delle licenze' },
    { name: 6, description: 'Gestione completa dei clienti' },
    { name: 7, description: 'Gestione completa dei PC' }
  ];

  constructor(private api: RolesApiService, private route: ActivatedRoute, ) {
  }

  ngOnInit() {
    this.api.getKeys().subscribe(keys => {
      this.permArr = keys;
      this.flagpermArr = true
    });

    this.route.data.pipe(
      map(data => data.cres)).subscribe((key) => {
        this.permArrResolved = key;
        this.flagpermpermArrResolved = true
      });
  }
于 2018-08-02T09:17:57.937 回答
0

你可以使用:

<ng-container *ngIf="permArr && permArrResolved"> your code here </ng-container>

只有当 permArr 和 perArrResoved 中有数据时才会呈现容器内容。

于 2018-08-02T09:21:50.840 回答