简体   繁体   中英

Angular Material List Option returns true, even if false

<mat-selection-list>
    <ng-container *ngFor="let cat of permissionCategories()">
        <mat-divider></mat-divider>
        <div mat-subheader>{{ cat }}</div>
        <mat-list-option *ngFor="let permission of permissionsOfCategory(cat)"
            [selected]="havePermission(permission)"
        >
            {{ permission.Name }}
        </mat-list-option>
    </ng-container>
</mat-selection-list>

And

havePermission(permission: Permission): boolean {
    return this.currentRankPermissions.includes(permission.Id);
}

I checked houndred times all values, and they are correct There are some permissions and havePermission returns true or false

UseLspdTablet true
ModifyRanks true
AccessCitizenIndex true
AccessCitizenRegistry false
ArrestMandateCitizen false
ChangeCitizenPhoneNumber false
ModifyCitizenWanted false
ShowCitizenCrimeCount false
AccessVehicleIndex false
SetVehicleAsStolen false
SetVehicleAsWanted false
SetVehicleAsFound false
SetVehicleNote false

And every time I run this page, everything works perfectly, but then I wait 3 seconds (after this time there are some other updates on same page, none of them are accessing any of this variables or something ) and then in console they still show ok, but in page they all are selected, WHY

Also I noticed that there are thousends of console logs of this = thousends of rerenders.

Rest of maybe important code:

  onTablesChanged() {
    this.allRanks = Array.from(this.db.Tables.Rank.values());

    if (this.permissionsOfRank.length <= 0) {
      this.permissionsOfRank = Array.from(this.db.Tables.PermissionOfRank.values());
    }
  }

  permissionCategories(): string[] {
    const res = [];
    Array.from(this.db.Tables.Permission.values()).forEach((permission: Permission) => {
      if (!res.includes(permission.Category)) {
        res.push(permission.Category);
      }
    });

    return res;
  }

  permissionsOfCategory(cat: string): Permission[] {
    return Array.from(this.db.Tables.Permission.values())
      .filter(c => c.Category === cat);
  }

Every 3 seconds onTablesChanged is called which cause this rerender, but it should cause 13 calls of havePermission , but it cause 99999999 of them, WHY

Windows 10 Angular 8.3.26 Typescript 3.5.3 @angular/material 8.2.3

I ran this on FiveM Application (GTA V) - which just use chromium.

WHY

In general use a function in the.html is bad idea. I suppose your permissionCategories and permissionsOfCategory changes when the tables changes, that's you can mannage in the onTablesChanged. So you can use this function to calculate a variable data that was an array of object. Each object has two properties: category and permissions (this last is an array). So:

data:any[] //<--declare a variable
onTablesChanged() {
    this.allRanks = Array.from(this.db.Tables.Rank.values());

    if (this.permissionsOfRank.length <= 0) {
      this.permissionsOfRank = Array.from(this.db.Tables.PermissionOfRank.values());
    }
    //here calculate data in the way
    data=this.permissionCategories().map(x=>({category:x,permissions:[]}))
    //data is an array ob object with "category" and "permissions"
    data.forEach(x=>{
      //with each element of data
       x.permissions=this.permissionsOfCategory(x.category)
          //x.permisions is an array of Permision, but 
          //you create an object with "permision", the Permision and "selected"
          .map(p=>({
               permission:p,
               selected:this.havePermission(x.category)
          })
    })
  }

And your.html

<mat-selection-list>
    <ng-container *ngFor="let cat of data">
        <mat-divider></mat-divider>
        <!--use cat.category-->
        <div mat-subheader>{{ cat.category }}</div>
                <!--use cat.permissions-->
        <mat-list-option *ngFor="let permission of cat.permissions"
            <!--use 
            [selected]="permission.selected"
        >
            {{ permission.permission.Name }}
        </mat-list-option>
    </ng-container>
</mat-selection-list>

I hope don't missing so much (I don't check the code), but remember: the idea is calculate all one time -using map to transform an array in an array of objects (one property the array and another property a value calculated) instead use complex function in the.html

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM