簡體   English   中英

如何從 Angular2 FormControl 對象獲取輸入字段的名稱?

[英]How to get name of input field from Angular2 FormControl object?

我有一個 Angular 2 應用程序,它使用ReactiveForms模塊來管理使用自定義驗證器的表單。 驗證器接收一個FormControl對象。 我有幾個輸入字段可以使用相同的自定義驗證器,前提是我在將FormControl傳遞給驗證器時知道字段的名稱。

我在FormControl上找不到任何公開輸入字段名稱的方法或公共屬性。 當然,很簡單就能看出它的價值。 下面顯示了我想如何使用它:

public asyncValidator(control: FormControl): {[key: string]: any} {
  var theFieldName = control.someMethodOfGettingTheName(); // this is the missing piece

  return new Promise(resolve => {
      this.myService.getValidation(theFieldName, control.value)
        .subscribe(
          data => {
            console.log('Validation success:', data);
            resolve(null);
          },
          err => {
            console.log('Validation failure:', err);
            resolve(err._body);
          });
    });
  }

擴展 Radim Köhler 的答案。 這是編寫該函數的較短方法。

getControlName(c: AbstractControl): string | null {
    const formGroup = c.parent.controls;
    return Object.keys(formGroup).find(name => c === formGroup[name]) || null;
}

我們可以使用.parent屬性,今天["_parent"] (見下文)

export const getControlName = (control: ng.forms.AbstractControl) =>
{
    var controlName = null;
    var parent = control["_parent"];

    // only such parent, which is FormGroup, has a dictionary 
    // with control-names as a key and a form-control as a value
    if (parent instanceof ng.forms.FormGroup)
    {
        // now we will iterate those keys (i.e. names of controls)
        Object.keys(parent.controls).forEach((name) =>
        {
            // and compare the passed control and 
            // a child control of a parent - with provided name (we iterate them all)
            if (control === parent.controls[name])
            {
                // both are same: control passed to Validator
                //  and this child - are the same references
                controlName = name;
            }
        });
    }
    // we either found a name or simply return null
    return controlName;
}

現在我們准備調整我們的驗證器定義

public asyncValidator(control: FormControl): {[key: string]: any} {
  //var theFieldName = control.someMethodOfGettingTheName(); // this is the missing piece
  var theFieldName = getControlName(control); 
  ...

.parent以后, ["_parent"]現在

目前(今天,現在) ,當前版本是:

2.1.2 (2016-10-27)

但是在這個問題之后: feat(forms): make 'parent' a public property of 'AbstractControl'

正如這里已經說明的那樣

2.2.0-beta.0 (2016-10-20)

特點

  • 表單:使 'parent' 成為 'AbstractControl' 的公共屬性 (#11855) (445e592)
  • ...

我們可以稍后將["_parent"]更改為.parent

從 Angular 4.2.x 開始,您可以使用公共屬性訪問FormControl的父FormGroup (及其控件):

private formControl: FormControl;

//...

Object.keys(this.formControl.parent.controls).forEach((key: string) => {
  // ...
});

您有兩個選擇:

Attribute裝飾器的幫助下:

constructor(@Attribute('formControlName') public formControlName) {}

Input裝飾器的幫助下:

@Input() formControlName;

要使用它,您的驗證當然需要是一個指令。

您可以在驗證器中設置控件名稱:

this.form = this.fb.group({
     controlName: ['', 
         [
            Validators.required, 
            (c) => this.validate(c, 'controlName')
         ]
      ]
});

然后:

validate(c: FormControl, name) {
    return name === 'controlName' ? {invalid: true} : null;
}

不完全是您想要的,但您可以像某些示例中那樣動態創建驗證器。

喜歡

typeBasedValidator(controlName: string): ValidatorFn {
  return(control: AbstractControl): {[key: string]: any} => {
     // Your code using controlName to validate
     if(controlName == "something") { 
       doSomething(); 
     } else { 
       doSomethingElse(); 
     }
  }
}

然后在創建表單時使用驗證器,傳遞控件名稱,如

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM