2017-10-30 3 views
0

In meinem Angular 4 Projekt möchte ich eine meiner 2 Tabellen basierend auf dem Wert einer Umschaltfläche anzeigen, wenn false ich erste Tabelle zeige, wenn true ich zweite Tabelle zeige.Wie man ExpressionChangedAfterItHasBeenCheckedError beim Umschalten vermeidet

Ich verwende primeng Datentabelle in einem div wie folgt aus:

<div *ngIf="checked"> 
    <p-dataTable [value]="models" [rows]="10"[paginator]="true".... 
</div> 

Und das Toggle ist

<mat-slide-toggle labelPosition="before" [(ngModel)]="checked"> 
{{first table }}</mat-slide-toggle> 

Aber wenn ich auf den Schalter klicken Ich habe:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'.

Wie kann ich diesen Fehler vermeiden?

Dies ist die gesamte Komponente:

<div class="main-content"> 
    <div class="container-fluid"> 
     <div class="row"> 
      <div class="col-md-12"> 
       <div class="card"> 
        <div class="card-header card-header-icon" 
         data-background-color="main-theme-color"> 
         <i class="material-icons">euro_symbol</i> 
        </div> 
        <div class="card-content"> 
         <h4 class="card-title">{{'movement.table.titles.header' | 
          translate }}</h4> 
         <div class="row"> 
          <div class="col-md-2 col-md-offset-10"> 
           <!-- matTooltip="Like" [matTooltipPosition]="'left'" 
           title="{{'movement.table.tooltips.add' | translate }}"--> 
           <button type="button" class="btn btn-info btn-round pull-right" 
            (click)="routeToView(['/movements/new'])" 
            matTooltip="{{'movement.table.tooltips.add' | translate }}" 
            [matTooltipPosition]="'above'" 
            [matTooltipShowDelay]="tooltipShowDelay" 
            [matTooltipHideDelay]="tooltipHideDelay"> 
            <span class="btn-label"> <i class="material-icons">add</i> 
            </span> 
           </button> 
          </div> 
         </div> 

         <div class="row"> 
          <div class="col-md-2"> 
           <mat-slide-toggle labelPosition="before" [(ngModel)]="checked">{{'movement.table.toggle.competenceview' 
           | translate }}</mat-slide-toggle> 
          </div> 
          <div class="col-md-2"> 
           <label class="pull-right">{{'movement.table.toggle.financialview' 
            | translate }}</label> 
          </div> 
         </div> 

         <div class="col-md-12" *ngIf="checked"> 
          <div class="content table-responsive"> 
           <p-dataTable #dt [value]="models" [rows]="defaultPageSize" 
            [paginator]="true" [rowsPerPageOptions]="pageSizeOptions" 
            [responsive]="true" resizableColumns="true" [lazy]="true" 
            [totalRecords]="totalElements" sortField="createdDate" 
            [sortOrder]="-1" (onLazyLoad)="loadDataIntoTable($event)" 
            [loading]="loader" reorderableColumns="true"> <p-column 
            field="createdDate" [sortable]="true" 
            header="{{'movement.table.headers.date' | translate }}"> 
           <ng-template let-col let-date="rowData" pTemplate="body"> 
           <span> {{date[col.field] | formatdate | date 
            :('pattern.datehourmin' | translate)}} </span> </ng-template></p-column> <p-column 
            field="currencyDate" [sortable]="true" 
            header="{{'movement.table.headers.currencydate' | translate }}"> 
           <ng-template let-col let-date="rowData" pTemplate="body"> 
           <span> {{date[col.field] | formatdate | date 
            :('pattern.date' | translate)}} </span> </ng-template></p-column> <p-column field="description" 
            header="{{'movement.table.headers.description' | 
          translate }}" 
            [sortable]="true"> <ng-template 
            let-movement="rowData" pTemplate="body"> <span 
            *ngIf="movement.refundId || movement.ticketBundleId" 
            class="crosslink" (click)="selectDescription(movement)">{{movement.description}}</span> 
           <span 
            *ngIf="movement.refundId === undefined && movement.ticketBundleId === undefined">{{movement.description}}</span> 
           </ng-template> </p-column> <p-column field="paymentTypeName" 
            header="{{'movement.table.headers.paymenttypename' | 
          translate }}" 
            [sortable]="true"></p-column> <p-column field="amount" 
            header="{{'movement.table.headers.amount' | translate }}" 
            [sortable]="true"> <ng-template let-col 
            let-amount="rowData" pTemplate="body"> <span 
            [style.color]="amount[col.field] < 0 ? 'red' : 'green'"> 
            {{amount[col.field] | currency:'EUR':true}} </span> </ng-template></p-column> <p-column 
            styleClass="col-button"> <ng-template 
            let-model="rowData" pTemplate="body"> 

           <div class="text-center"> 
            <span><button 
              class="btn btn-simple btn-success btn-icon edit" 
              (click)="selectModel(model)" 
              matTooltip="{{'movement.table.tooltips.view' | translate }}" 
              [matTooltipPosition]="'left'" 
              [matTooltipShowDelay]="tooltipShowDelay" 
              [matTooltipHideDelay]="tooltipHideDelay"> 
              <i class="material-icons">dvr</i> 
             </button> </span> 
           </div> 
           </ng-template> </p-column> </p-dataTable> 

          </div> 
         </div> 

         <div class="col-md-12" *ngIf="!checked"> 
          <div class="content table-responsive"> 
           <p-dataTable #dt [value]="models" [rows]="defaultPageSize" 
            [paginator]="true" [rowsPerPageOptions]="pageSizeOptions" 
            [responsive]="true" resizableColumns="true" [lazy]="true" 
            [totalRecords]="totalElements" sortField="createdDate" 
            [sortOrder]="-1" (onLazyLoad)="loadDataIntoTable($event)" 
            [loading]="loader" reorderableColumns="true"> <p-column 
            field="createdDate" [sortable]="true" 
            header="{{'movement.table.headers.date' | translate }}"> 
           <ng-template let-col let-date="rowData" pTemplate="body"> 
           <span> {{date[col.field] | formatdate | date 
            :('pattern.datehourmin' | translate)}} </span> </ng-template></p-column> <p-column 
            field="currencyDate" [sortable]="true" 
            header="{{'movement.table.headers.currencydate' | translate }}"> 
           <ng-template let-col let-date="rowData" pTemplate="body"> 
           <span> {{date[col.field] | formatdate | date 
            :('pattern.date' | translate)}} </span> </ng-template></p-column> <p-column field="description" 
            header="{{'movement.table.headers.description' | 
          translate }}" 
            [sortable]="true"> <ng-template 
            let-movement="rowData" pTemplate="body"> <span 
            *ngIf="movement.refundId || movement.ticketBundleId" 
            class="crosslink" (click)="selectDescription(movement)">{{movement.description}}</span> 
           <span 
            *ngIf="movement.refundId === undefined && movement.ticketBundleId === undefined">{{movement.description}}</span> 
           </ng-template> </p-column> <p-column field="paymentTypeName" 
            header="{{'movement.table.headers.paymenttypename' | 
          translate }}" 
            [sortable]="true"></p-column> <p-column field="amount" 
            header="{{'movement.table.headers.amount' | translate }}" 
            [sortable]="true"> <ng-template let-col 
            let-amount="rowData" pTemplate="body"> <span 
            [style.color]="amount[col.field] < 0 ? 'red' : 'green'"> 
            {{amount[col.field] | currency:'EUR':true}} </span> </ng-template></p-column> <p-column 
            styleClass="col-button"> <ng-template 
            let-model="rowData" pTemplate="body"> 

           <div class="text-center"> 
            <span><button 
              class="btn btn-simple btn-success btn-icon edit" 
              (click)="selectModel(model)" 
              matTooltip="{{'movement.table.tooltips.view' | translate }}" 
              [matTooltipPosition]="'left'" 
              [matTooltipShowDelay]="tooltipShowDelay" 
              [matTooltipHideDelay]="tooltipHideDelay"> 
              <i class="material-icons">dvr</i> 
             </button> </span> 
           </div> 
           </ng-template> </p-column> </p-dataTable> 

          </div> 
         </div> 


        </div> 
       </div> 
       <!-- end card --> 
      </div> 
      <!-- end col-md-12 --> 
      <!-- end row --> 
     </div> 
    </div> 
</div> 
+1

Ich kann nichts falsch in diesem Code sehen. Gibt es weitere Informationen darüber, welcher Code den Fehler verursacht hat? –

+0

Können Sie Ihre Frage mit der Komponentenklasse aktualisieren? – RagnarLothbrok

+0

@llqadude aktualisiert – Alessandro

Antwort

0

Ich war dieses ExpressionChangedAfterItHasBeenCheckedError bekommen, wenn PrimeNG Dialoge, insbesondere, wenn entweder ein Drop-Down oder ein Optionsfeld war die erste Komponente, die den Fokus nahm. Von diesem Thread hier:

https://github.com/primefaces/primeng/issues/4139

... es sieht aus wie ein PrimeNG Fehler, nicht nur ist etwas, das Mensch falsch PrimeNG mit zu tun.

fand ich eine Abhilfe, die ich bin nicht verrückt, aber es scheint, den Job für mich jetzt zu erledigen:

// Patches for PrimeNG focus bugs. 
import { Dropdown, RadioButton } from 'primeng/primeng'; 

const originalDropdownOnInputFocus = Dropdown.prototype.onInputFocus; 
Dropdown.prototype.onInputFocus = function(event: any): void { 
    setTimeout(() => { 
    originalDropdownOnInputFocus.call(this, event); 
    }); 
}; 

const originalRadioButtonOnFocus = RadioButton.prototype.onFocus; 
RadioButton.prototype.onFocus = function(event: any): void { 
    setTimeout(() => { 
    originalRadioButtonOnFocus.call(this, event); 
    }); 
}; 

Dies keine erschöpfende fix sein soll, ist es lediglich fixiert die spezifische Probleme hatte ich in meiner eigenen App mit Fokus auf ein P-Drop-Down und ein P-RadioButton. Hoffentlich kann dieses Muster verfolgt werden, um andere Fehler zu beheben.

Natürlich werde ich gespannt auf eine echte Lösung in PrimeNG selbst warten, damit ich diese Problemumgehung löschen kann.

Verwandte Themen