简体   繁体   English

Angular:将查询参数绑定到 ExpressionChangedAfterItHasBeenCheckedError 中的表单字段结果

[英]Angular : bind query parameter to form field results in ExpressionChangedAfterItHasBeenCheckedError

I created a simple directive which takes input from a queryparam and patches the value of a form input.我创建了一个简单的指令,它从查询参数中获取输入并修补表单输入的值。 The directive works fine, but I'm receiving this error ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'null'. Current value: 'testuser@test.be'该指令工作正常,但我收到此错误ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'null'. Current value: 'testuser@test.be' ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'null'. Current value: 'testuser@test.be' ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'null'. Current value: 'testuser@test.be' . ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'null'. Current value: 'testuser@test.be'

I searched for solutions on SO / Google and tried a few like putting the logic of ngOnInit of my directive in ngAfterContentChecked or ngAfterContentInit, but the error is still there... Can anybody point me in the right direction to solve this?我在 SO / Google 上搜索了解决方案并尝试了一些,比如将我的指令的 ngOnInit 逻辑放在 ngAfterContentChecked 或 ngAfterContentInit 中,但错误仍然存在......任何人都可以指出我正确的方向来解决这个问题吗?

Directive 'bindQueryParamToInput'指令“bindQueryParamToInput”

import { Directive, Input } from '@angular/core';
import { NgControl } from '@angular/forms';

@Directive({
  selector: '[bindQueryParamToInput]'
})
export class BindQueryparamToInputDirective {
  @Input('bindQueryParamToInput') paramKey: string;

  constructor( private ngControl : NgControl) { }

  ngOnInit() {
    const queryParams = new URLSearchParams(location.search);

    if (queryParams.has(this.paramKey)) {
      this.ngControl.control.patchValue(queryParams.get(this.paramKey));
    }
  }

}

component.html in which the directive is used on email field component.html 其中指令用于 email 字段

<div class="form-group" formGroupName="localAccountData">
    <label>Emailadres</label>
    <input formControlName="email"
           type="text" 
           class="form-control"
           placeholder="Email (login)"
           bindQueryParamToInput="e">
</div>

component.ts where the form is initialized component.ts 表单初始化的地方

@Component({
  selector: 'gimmi-register',
  templateUrl: './register.component.html',
  styleUrls: ['./register.component.css']
})
export class RegisterComponent implements OnInit {
  registrationForm: FormGroup;

  constructor( ) { }

  ngOnInit(): void {
    this.registrationForm = new FormGroup ({
      'personData': new FormGroup({
        'firstName': new FormControl(null, Validators.required),
        'lastName': new FormControl(null, Validators.required),
        'birthday': new FormControl(null, Validators.required)
      }),
      'localAccountData': new FormGroup({
        'email': new FormControl(null, [Validators.required, Validators.email]),
        'password': new FormControl(null, [Validators.required])
      })
    });
  }
}

EDIT : The accepted solution works in the above scenario.编辑:接受的解决方案适用于上述情况。 But now I've put the email field in a separate component (the directive is now used in the subcomponent) and now the ExpressionChangedAfterItHasBeenCheckedError is back... :-(但是现在我已经将 email 字段放在一个单独的组件中(该指令现在在子组件中使用)现在ExpressionChangedAfterItHasBeenCheckedError又回来了...... :-(

I already tried to use the solution and add this.ref.detectChanges() in the ngOnInit of the subcomponent, but it didn't work...我已经尝试使用该解决方案并在子组件的 ngOnInit 中添加this.ref.detectChanges() ,但它没有用......

Is there something extra I need to do to solve this problem in the subcomponent?我需要做些什么来解决子组件中的这个问题吗?

subcomponent email-input.ts子组件 email-input.ts

import { Component, Input, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms';

@Component({
  selector: 'email-input',
  templateUrl: './email-input.component.html',
  styleUrls: ['./email-input.component.css']
})
export class EmailInputComponent implements OnInit {
  @Input() parentFormGroup: FormGroup;

  constructor() { }

  ngOnInit(): void {
    this.parentFormGroup.addControl( 'email', new FormControl(null, [Validators.required, Validators.email]));
  }
}

subcomponent email-input.html (where the directive is used)子组件 email-input.html(使用指令的地方)

div [formGroup]='parentFormGroup'>
        <input  formControlName="email" 
                type="text" 
                class="form-control" 
                placeholder="Email (login)" 
                bindQueryParamToInput="e">
</div>

In the component.html, I only use the <email-input></email-input> component now.在component.html中,我现在只使用<email-input></email-input>组件。

Another "standard" solution would be imperatively ordering change detection.另一个“标准”解决方案是强制性地订购变更检测。

  constructor( private ngControl : NgControl, private ref: ChangeDetectorRef) { }

  ngOnInit() {
    const queryParams = new URLSearchParams(location.search);

    if (queryParams.has(this.paramKey)) {
      this.ngControl.control.patchValue(queryParams.get(this.paramKey));
      this.ref.markForCheck();

      // or, alternatively
      this.ref.detectChanges();
    }
  }

I solved the problem I described in the edit by changing putting a setTimeout around the line that update form control value.我通过更改在更新表单控件值的行周围放置setTimeout解决了我在编辑中描述的问题。

setTimeout(() => {
  this.ngControl.control.patchValue(queryParams.get(this.paramKey));
});

This works, but it feels like a workaround and not like a solid solution... So any help to get a better solution is much appreciated这行得通,但感觉像是一种解决方法,而不是可靠的解决方案......因此非常感谢任何帮助获得更好解决方案的帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Angular 7 表单 ExpressionChangedAfterItHasBeenCheckedError - 带有条件输入字段 - Angular 7 Form ExpressionChangedAfterItHasBeenCheckedError - with conditional Input Field 表单验证中的 Angular 5 ExpressionChangedAfterItHasBeenCheckedError - Angular 5 ExpressionChangedAfterItHasBeenCheckedError on form validation 自定义表单控件上的角度ExpressionChangedAfterItHaHasBeenCheckedError - Angular ExpressionChangedAfterItHasBeenCheckedError on custom form control 表单的Angular 4加载数据服务引发ExpressionChangedAfterItHaHasBeenCheckedError - Angular 4 Load Data Service for Form throws ExpressionChangedAfterItHasBeenCheckedError Angular Reactive Form手动验证给出了ExpressionChangedAfterItHaHasBeenCheckedError - Angular Reactive Form manual validate gives ExpressionChangedAfterItHasBeenCheckedError Angular 8 ExpressionChangedAfterItHasBeenCheckedError 反应形式的无线电验证 - Angular 8 ExpressionChangedAfterItHasBeenCheckedError radio validation on reactive form 如何以角度将数据绑定到垫子表单字段? - How to bind data to a mat form field in angular? Angular 2 - 如何绑定到“动态”表单字段 - Angular 2 - how to bind to a "dynamic" form field ExpressionChangedAfterItHasBeenCheckedError:角度 - ExpressionChangedAfterItHasBeenCheckedError: angular ExpressionChangedAfterItHasBeenCheckedError Angular - ExpressionChangedAfterItHasBeenCheckedError Angular
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM