2017-03-07 3 views
1

Ich habe ein Problem, wo, wenn das letzte Element in meinem Formular einen Wert gebunden hat der Fehler "Ausdruck hat sich geändert, nachdem es überprüft wurde." ist geworfen.Angular 2/PrimeNG - Der Ausdruck hat sich nach der Überprüfung geändert. Binding NgModel auf letzten ungültigen Formular Steuerelement

ich sagen, dieses Vorwort wird basiert hier der Angular 2 Website Beispiel aus - https://angular.io/docs/ts/latest/cookbook/dynamic-form.html#!#top

Die Art und Weise meine Anwendung funktioniert, ist zunächst ich eine dynamische Form mit Kontrollen in meiner Form Komponente ein Modell basiert weg bauen.

Meine Form Komponenten html schleift die Fragen in dem Modell wie so

<form *ngIf="showForm" [formGroup]="formGroup"> 
    <!-- questions--> 
    <div *ngIf="questions.length > 0"> 
     <div *ngFor="let question of questions"> 
      <question [question]="question" [formGroup]="formGroup"></question> 
     </div> 
    </div> 
    <button pButton type="submit" label="Submit" icon="fa-check-circle-o" iconPos="left" 
      [disabled]="!formGroup.valid" (click)="submitFinalForm()"></button> 
</form> 

Unten ist die Frage Komponente HTML, die die Daten verwendet, die in der Form Komponente übergeben wurden bestimmte Arten von Fragen über ngSwitch

anzuzeigen
<label [attr.for]="question.field"> 
    {{ question.question }} 
</label> 
<div [ngSwitch]="question.type"> 
    <!-- Radio/Checkbox --> 
    <radio-checkbox-question *ngSwitchCase="1" [formGroup]="formGroup" [question]="question"></radio-checkbox-question> 
</div> 

Schließlich ist hier die Radio-Checkbox-Frage Komponente

<div *ngIf="showQuestion" [formGroup]="formGroup"> 
    <!-- Radio --> 
    <div *ngIf="model.radiocheckbox == 'radio'"> 
     <div *ngFor="let label of model.labels; let i = index;"> 
      <p-radioButton name="{{model.field}}" 
          value="{{i}}" 
          label="{{label}}" 
          formControlName="{{model.field}}" 
          [(ngModel)]="questionAnswerRadio"></p-radioButton> 
     </div> 
    </div> 
</div> 

Hier ist die eigentliche Komponente TS

import { Component, Input, OnInit }   from "@angular/core"; 
import { FormGroup }      from "@angular/forms"; 

import { RadioCheckboxQuestion }   from "../Questions/radio.checkbox.question.model"; 

@Component({ 
    selector: "radio-checkbox-question", 
    templateUrl: "radio.checkbox.component.html" 
}) 
export class RadioCheckboxComponent implements OnInit { 

    @Input() question: any; 
    @Input() formGroup: FormGroup; 

    model: RadioCheckboxQuestion = new RadioCheckboxQuestion(); 
    showQuestion: boolean = false; 

    questionAnswerRadio: string = ""; 

    ngOnInit(): void { 
     // question essential properties 
     if (this.question.hasOwnProperty("field") && this.question["field"] && 
      this.question.hasOwnProperty("labels") && this.question["labels"]) { 
      this.model.field = this.question["field"]; 
      this.model.labels = this.question["labels"]; 

      // assume always radio for debugging 
      this.model.radiocheckbox = "radio"; 

      // set existing answer 
      if (this.question.hasOwnProperty("QuestionAnswer") && this.question["QuestionAnswer"]) { 
       if (this.model.radiocheckbox == "radio") { 
        this.questionAnswerRadio = this.question["QuestionAnswer"]; 
       } 
      } 

      this.showQuestion = true; 
     } 
    } 
} 

ich auch viele SO Fragen wie die folgenden Angular 2 dynamic forms example with ngmodel results in "expression has changed after it was checked" gesehen haben, welche im Grunde sagen, dass [(ngModel)] nicht mit dynamischen Formen verwendet werden, aber die primeNG Dokumentation sagt Die Komponenten können mit modellgesteuerten Formen arbeiten, und die einzige Möglichkeit, die Antwort (die ich kenne) zu setzen, ist [(ngModel)]. Ich glaube, dass hier etwas passieren könnte, ist, da ich die einzige Frage in der formGroup auf einen Wert eingestellt, dass die formGroup zwischen der Änderungserkennung gültig wird und bewirkt, dass der Fehler

Error in ./FormComponent class FormComponent - inline template:17:48 caused by: Expression has changed after it was checked. Previous value: 'false'. Current value: 'true'.

+0

Können Sie auch Plunker erstellen? – yurzui

+0

Ich bin mir nicht sicher, wie man die neuesten Versionen von Angular 2 und PrimeNG plündert, es sieht so aus, als seien sie veraltet? Etwas komisches ist das in meiner Formularkomponente, wenn ich ChangeDetectionStrategy, ChangeDetectorRef importiere und changeDetection: ChangeDetectionStrategy.OnPush zusammen mit dem privaten cd verwende: ChangeDetectorRef und this.cd.markForCheck(); Um meine Formularkomponente manuell zu aktualisieren, tritt das Problem dann nicht mehr auf, aber in der vollständigen Version des Formulars sind die Textfeldeingaben von PrimeNG ausgefüllt und die Radio/Checkbox-Schaltflächen nicht. – user3333134

Antwort

0

Den einzigen Weg, ich gefunden habe Holen Sie sich die Änderungserkennung, um mit meinen multi-geschachtelten Komponenten zufrieden zu sein, und primeNG sollte die vollständige Änderungserkennung manuell implementieren. Was das bedeutet im Grunde war in jeder Komponente hatte ich so etwas wie die folgenden

import ChangeDetectorRef 

constructor(private change: ChangeDetectorRef) 
{} 

ngOnInit() { 

    // code here that inits everything 
    this.change.markForCheck(); 
} 

etwas hinzuzufügen weniger als dies verursachte die Änderung Erfassungsfehler in verschiedenen und einzigartigen Möglichkeiten, die in den Komponenten, um Pop-up, das primeNG verwendet.

0

Von Ihrer Vorlage sieht es so aus, als ob Sie beide Modell-Laufwerk (FormControlName) und Vorlage (ngModel) verwendet.

<p-radioButton name="{{model.field}}" 
          value="{{i}}" 
          label="{{label}}" 
          formControlName="{{model.field}}" 
          [(ngModel)]="questionAnswerRadio"></p- 
    <radioButton> 

Bitte wählen Sie einen Weg und versuchen Sie es erneut. Ich schlage vor, Sie entfernen die [(ngModel)]

Verwandte Themen