2017-08-04 8 views
0

マイテンプレート:角度カスタムバリデータに配列を渡し

  <input mdInput 
       [mdAutocomplete]="auto" 
       [(ngModel)]="formData.areaName" 
       (keyup)="updateFilteredAreas(formData.areaName)" 
       class="form-control {{areaName.errors && (areaName.dirty || areaName.touched) ? 'failed-validation' : ''}}" 
       name="areaName" 
       #areaName="ngModel" 
       arrayIncludes="one,two,three" 
       required> 

      <div *ngIf="areaName.errors && (areaName.dirty || areaName.touched)" 
       [hidden]="!areaName.errors.arrayIncludes" 
       class="validation-error"> 
      Please enter a value from the array 
      </div> 

マイカスタムバリデータ:

export class CustomValidators { 

    public static arrayIncludes(arrayIncludes: string): ValidatorFn { 
    return (control: AbstractControl): { [key: string]: any } => { 
     if (isPresent(Validators.required(control))) { 
     return null; 
     } 

     let arrayFromString = arrayIncludes.split(","); 

     let value: string = control.value; 

     return arrayFromString.includes(value) ? 
     null : 
     { arrayIncludes: { valid: false } }; 
    }; 
    } 
} 

ヘルパー機能:

function isPresent(obj) { 
    return obj !== undefined && obj !== null; 
} 

検証ディレクティブ:

const ARRAY_INCLUDES_VALIDATOR = { 
    provide: NG_VALIDATORS, 
    useExisting: forwardRef(() => ArrayIncludesValidator), 
    multi: true 
}; 

@Directive({ 
    selector: '[arrayIncludes][ngControl],[arrayIncludes][ngFormControl],[arrayIncludes][ngModel]', 
    providers: [ARRAY_INCLUDES_VALIDATOR] 
}) 
export class ArrayIncludesValidator implements Validator { 
    private _validator: any; 

    constructor(@Attribute('arrayIncludes') arrayIncludes: string) { 
    this._validator = CustomValidators.arrayIncludes(arrayIncludes); 
    } 

    public validate(control: AbstractControl): {[key: string]: any} { return this._validator(control); } 
} 

これまでのところ、私は、テンプレート内のディレクティブの値として文字列を置くことができます。

arrayIncludes="one,two,three" 

と、結果はそれが唯一の「1」、「2」であると、文字列を配列に変換し、 " 3つの値が許可されます。私が必要とするのは、コントローラからオブジェクトの配列であるディレクティブにオブジェクトを渡すことです。それらのオブジェクトにはpropery "area.name"があり、各 "area.name"は有効な入力です。私は構文を使用する場合:「filteredAreasは」私の対象であると

[arrayIncludes]="filteredAreas" 

を、私が手にエラーは、私は、テンプレートを経由して、オブジェクトを受け入れるように、私のカスタムバリデータをリファクタリングするにはどうすればよい

Error: Template parse errors: 
Can't bind to 'arrayIncludes' since it isn't a known property of 'input'. (" 
       name="areaName" 
       #areaName="ngModel" 
       [ERROR ->][arrayIncludes]="filteredAreas" 
       required> 

"): ng:///RegistrationModule/[email protected]:21 

です。それは "@Input"デコレータと関係があります。私の問題はこのthreadと非常によく似ていますが、必要な情報が不足しているようです。

答えて

2

オブジェクトを渡したい場合は、@Input代わりの@Attribute

@Directive({...}) 
export class ArrayIncludesValidator implements Validator { 
    private _validator: any; 

    @Input() arrayIncludes: any; 

    ngOnInit() { 
    this._validator = CustomValidators.arrayIncludes(this.arrayIncludes); 
    } 

    public validate(control: AbstractControl): {[key: string]: any} { return this._validator(control); } 
} 
を使用する必要があります
関連する問題