アプリコンポーネント、子コンポーネント(アカウント)、メッセージダイアログコンポーネント(ポップアップモーダル)を処理するアラートサービスを備えた非常にシンプルなアプリがあります。
目的を示すために、app.component.ts内とaccount.component.ts内の2つの同一のフォームがあります。それぞれに、アラートサービスを呼び出してメッセージダイアログをモーダルで表示するボタンがあります。
問題は、子コンポーネント(account.component.ts)のフォームの入力フィールドをクリックして、「キーボードのEnterキーを押す」と、このエラーが発生することです。
例外:./ AccountComponentクラスAccountComponentのエラー-インラインテンプレート:2:2原因:式がチェックされた後に変更されました。以前の値: 'true'。現在の値: 'false'。このエラーは、以下に説明する他の状況では発生しないことに注意してください
キーボードのEnterキーを押す代わりにボタンをクリックした場合
Enterキーを押しても、app.componen.tsのフォームに問題はないようです。子コンポーネント(accouunt.component.ts)だけのようです。
account.componentの入力をクリックし、何かを入力し、ボタンをクリックすると、エラーは表示されません。入力を削除し、Enterキーを押します。以前と比較して、エラーは表示されません。
私はSOとグーグルを調べましたが、人々は同じ問題を抱えており、変更検出を呼び出すことでそれを解決しているようです。しかし、それを試してみて、モーダルが表示された直後などに置いてみましたが、うまくいきませんでした。また、それで解決できる場合は、app.component.tsのフォームでこのエラーが発生しない理由が説明されていません。
以下はいくつかのコードスニペットです。完全なデモプロジェクトは上記のgithubリンクにあります。この問題は何日も私を悩ませてきました。助けてくれてありがとう。
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
エクスポートクラスAccountComponentは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
})
}
}
メッセージ-dialog.component.html
<div class="modal-header">
<h4 class="modal-title">{{titleText}}</h4>
</div>
<div class="modal-body">
<p>{{bodyText}}</p>
</div>
メッセージ-dialog.component.ts
export class MessageDialogComponent implements OnInit {
@Input() titleText: string;
@Input() bodyText: string;
constructor(
public activeModal: NgbActiveModal,
) { }
ngOnInit() {
}
}
次のコードの実行後にエラーが発生したようです。
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
oninput
はblur
、コントロールをとしてマークする発生イベントですtouched
。
それはのための作業をしないAccountComponent
で検出が変わるので、AccountComponent
前に発生しngbModalContainer
ている間FormGroup
内にapp.component.html
正しい値を取得します。
可能な解決策:
1)モーダルを開く前に、コントロールにタッチ済みのマークを付けます
account.component.ts
onUpdatePassword() {
Object.keys(this.changePasswordForm.controls).forEach(key => {
this.changePasswordForm.controls[key].markAsTouched();
});
this.alertService.alertPopup('test2', 'asfafa')
}
2)注文変更タグ
app.component.html
<template ngbModalContainer></template>
<router-outlet> </router-outlet>
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加