2017-02-19 3 views
2

Youtube video demonstrating the problemAngular 2 Modal Popup Fehler "Ausdruck geändert hat, nachdem er geprüft wurde"

Github repository for the demo app

Ich habe eine sehr einfache Anwendung, mit einer App-Komponente, ein Kind Komponente (Account), Alert-Service, der eine Griff Nachrichtendialogkomponente (Popup-modal).

Zu Demonstrationszwecken habe ich zwei identische Formulare, eines innerhalb von app.component.ts und eines innerhalb von account.component.ts. Jeder von ihnen hat eine Schaltfläche, die den Benachrichtigungsdienst aufruft, um den Nachrichtendialogmodus anzuzeigen.

Das Problem ist, dass, wenn ich in das Eingabefeld des Formulars klicken für das Kind Komponente (account.component.ts) und „drücken auf meiner Tastatur eingeben“, bekomme ich diese Fehler

AUSNAHME: Fehler in der ./AccountComponent-Klasse AccountComponent - Inline-Vorlage: 2: 2 verursacht durch: Der Ausdruck hat sich nach der Überprüfung geändert. Vorheriger Wert: 'wahr'. Aktueller Wert: 'false'. Beachten Sie, dass dieser Fehler Dosis nicht bei jeder anderen Situation unter

  1. erwähnt auftreten Wenn ich auf die Schaltfläche klicken, anstatt Druck auf der Tastatur eingeben

  2. Die Form von app.componen.ts scheint nicht jedes Problem zu haben, selbst wenn ich Enter drücke. Es scheint nur die untergeordnete Komponente (account.component.ts) zu sein.

  3. Wenn ich den Eingang für account.component klicken, geben Sie etwas, klicken Sie auf den Button, kein Fehler angezeigt, löschen Sie die Eingabe, drücken Sie die Eingabetaste, kein Fehler jetzt

    vor

Ich habe Look gezeigt vergleichen in SO und Google und es scheint, als ob die Menschen das gleiche Problem haben und lösen sie durch den Aufruf change detect. Allerdings habe ich das ausprobiert und stelle es an Stellen wie kurz nachdem Modal gezeigt wurde und es hat nicht funktioniert. Auch, wenn das das Problem lösen würde, dann erklärt das nicht, warum das Formular in app.component.ts diesen Fehler nicht verursacht.

Im Folgenden finden Sie einige Code-Schnipsel, das vollständige Demo-Projekt finden Sie oben auf dem GitHub-Link. Dieses Problem beschäftigt mich seit Tagen. Sehr geschätzt für die Hilfe.

app.component.html

<label>This form is from app.component.html</label> 
<form name="form" [formGroup]="changePasswordForm" (ngSubmit)="onUpdatePassword()"> 
    <input placeholder="Old Password" formControlName="oldPassword"> 
    <button class="btn btn-success">Update Password</button> 
</form> 

<br><br><br><br> 

<label>This form is from account.component.html</label> 
<router-outlet> </router-outlet> 

<template ngbModalContainer></template> 

app.component.ts

export class AppComponent implements OnInit { 

    private changePasswordForm: FormGroup; 

    constructor(
     private formBuilder: FormBuilder, 
     private alertService: AlertService, 
    ) { } 

    ngOnInit() { 
     this.changePasswordForm = this.formBuilder.group({ 
     oldPassword: [''], 
     }) 
    } 

    onUpdatePassword() { 
     this.alertService.alertPopup('test2', 'asfafa') 
    } 
} 

account.component.html

<form name="form" [formGroup]="changePasswordForm" (ngSubmit)="onUpdatePassword()"> 
    <input placeholder="Old Password" formControlName="oldPassword"> 
    <button class="btn btn-success">Update Password</button> 
</form> 

account.component.ts

Export Klasse AccountComponent im plements OnInit {

private changePasswordForm: FormGroup; 

    constructor(
    private formBuilder: FormBuilder, 
    private alertService: AlertService, 
) { } 

    ngOnInit() { 
    this.changePasswordForm = this.formBuilder.group({ 
     oldPassword: [''], 
    }) 
    } 

    onUpdatePassword() { 
    this.alertService.alertPopup('test2', 'asfafa') 
    } 
} 

alert.service.ts

@Injectable() 
export class AlertService { 
    private subject = new Subject<any>(); 
    private keepAfterNavigationChange = false; 

    constructor(
     private router: Router, 
     private modalService: NgbModal, 
    ) { } 


    alertPopup(title: string, content: string) { 
     // open modal to check if worked over night 
     const modalRef = this.modalService.open(MessageDialogComponent); 

     modalRef.componentInstance.titleText = title 
     modalRef.componentInstance.bodyText = content 

     modalRef.result 
      .then(response => { 
      }) 
      .catch(() => { 
       return 
      }) 
    } 
} 

Nachricht-dialog.component.html

<div class="modal-header"> 
    <h4 class="modal-title">{{titleText}}</h4> 
</div> 

<div class="modal-body"> 
    <p>{{bodyText}}</p> 
</div> 

Nachricht-dialog.component.ts

export class MessageDialogComponent implements OnInit { 

    @Input() titleText: string; 
    @Input() bodyText: string; 

    constructor(
    public activeModal: NgbActiveModal, 
) { } 

    ngOnInit() { 
    } 

} 

Screen shot

Antwort

4

versucht haben, zu lösen scheint, Ihre Fehler nach der Ausführung folgenden Code auftritt:

ngAfterViewInit() { 
    if (!this._elRef.nativeElement.contains(document.activeElement)) { 
     this._renderer.invokeElementMethod(this._elRef.nativeElement, 'focus', []); 
    } 
} 

https://github.com/ng-bootstrap/ng-bootstrap/blob/1.0.0-alpha.20/src/modal/modal-window.ts#L65

auf inputblur Ereignis ausgelöst wird, die Ihre Kontrolle markiert als touched.

funktioniert es nicht für AccountComponent weil Erkennung Änderungen in AccountComponent vor ngbModalContainer auftritt, während FormGroup innerhalb app.component.html richtigen Werte bekommt.

Mögliche Lösungen:

1) markieren Sie Ihre Kontrollen berührt wie vor dem Öffnen modalen

account.component.ts

onUpdatePassword() { 
    Object.keys(this.changePasswordForm.controls).forEach(key => { 
    this.changePasswordForm.controls[key].markAsTouched(); 
    }); 

    this.alertService.alertPopup('test2', 'asfafa') 
} 

2) Änderungsauftrag Tags

App .component.html

<template ngbModalContainer></template> 
<router-outlet> </router-outlet> 
+0

Vielen Dank! Einfache Lösung mit Option 2 !. Darf ich Sie bitten, herauszufinden, was das Problem war, da der Fehlercode nicht so aussagekräftig war, wo das Problem lag? – ErnieKev

+0

Ehrlich gesagt ist es sehr schwierig solche Fehler zu debuggen. Sie müssen wissen, wie die Änderungserkennung funktioniert und wie angular2 'factory' für jede Komponente generiert – yurzui

+0

Aber Sie haben es so schnell gemacht? Ich bin seit Tagen festgefahren. Vielen Dank! – ErnieKev

3

ich noch einmal durch denselben Fehler gegangen,

Verwenden ngAfterViewInit() in Ihrem appComponent statt ngOnInit.

Wenn das nicht nur

setTimeOut(function(){ 
//Your Code 
},1) 
+0

der einzige Code innerhalb meiner app.component.ts ngOnInit ist this.changePasswordForm = this.formBuilder.group .... Und setzen Sie es in ngAfterViewInit wird die FormGroup erwartet eine FormGroup-Instanz Fehler. Dasselbe gilt für die setTimeout-Funktion. – ErnieKev

+0

könnte es besser sein, wenn Sie Ihren Code auf PLNKR haben, Ok, ich werde von Github bekommen und überprüfen. – sudhir

+0

Vielen Dank Kumpel. Ich habe mit diesem Problem gekämpft. Ich bin mir nicht sicher, wie man das in Plunker einrichtet, da es angulares Material 2 und Bootstrap-Klasse beinhaltet, um das modale Arbeiten zu erhalten. – ErnieKev

Verwandte Themen