Make directive @Input required

前端 未结 8 482
無奈伤痛
無奈伤痛 2021-01-30 06:26

In AngularJs we could make a directive attribute required. How do we do that in Angular with @Input? The docs don\'t mention it.

Eg.

@Component({
  selec         


        
相关标签:
8条回答
  • 2021-01-30 07:09

    Check in ngOnInit() (inputs aren't yet set when the constructor is executed) whether the attribute has a value.

    Component({
        selector: 'my-dir',
        template: '<div></div>'
    })
    export class MyComponent implements OnInit, OnChanges {
        @Input() a:number; // Make this a required attribute. Throw an exception if it doesnt exist
        @Input() b:number;
    
        constructor(){
        }
    
        ngOnInit() {
           this.checkRequiredFields(this.a);
        }
    
        ngOnChanges(changes) {
           this.checkRequiredFields(this.a);
        }
    
        checkRequiredFields(input) {
           if(input === null) {
              throw new Error("Attribute 'a' is required");
           }
        }
    }
    

    You might also check in ngOnChanges(changes) {...} if the values wasn't set to null. See also https://angular.io/docs/ts/latest/api/core/OnChanges-interface.html

    0 讨论(0)
  • 2021-01-30 07:10

    Why not use the @angular/forms library to validate your @Inputs? The following solution:

    • Fails fast (not just when the @input value is accessed by the component for the first time)
    • Allows re-using rules that you've already used for your Angular forms

    Usage:

        export class MyComponent {
    
          @Input() propOne: string;
          @Input() propTwo: string;
    
          ngOnInit() {
            validateProps<MyComponent>(this, {
              propOne: [Validators.required, Validators.pattern('[a-zA-Z ]*')],
              propTwo: [Validators.required, Validators.minLength(5), myCustomRule()]
            })
          }
        }
    

    Utility function:

        import { FormArray, FormBuilder, ValidatorFn, FormControl } from '@angular/forms';
    
        export function validateProps<T>(cmp: T, ruleset: {[key in keyof T]?: ValidatorFn[]} ) {
          const toGroup = {};
          Object.keys(ruleset)
            .forEach(key => toGroup[key] = new FormControl(cmp[key], ruleset[key]));
          const formGroup = new FormBuilder().group(toGroup);
          formGroup.updateValueAndValidity();
          const validationResult = {};
          Object.keys(formGroup.controls)
            .filter(key => formGroup.controls[key].errors)
            .forEach(key => validationResult[key] = formGroup.controls[key].errors);
          if (Object.keys(validationResult).length) {
            throw new Error(`Input validation failed:\n ${JSON.stringify(validationResult, null, 2)}`);
          }
        }
    

    Stackblitz

    0 讨论(0)
提交回复
热议问题