Make directive @Input required

前端 未结 8 484
無奈伤痛
無奈伤痛 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:02

    Here is another TypeScript decorator based approach that is less complicated and easier to understand. It also supports Component inheritance.

    
    // Map of component name -> list of required properties
    let requiredInputs  = new Map();
    
    /**
     * Mark @Input() as required.
     *
     * Supports inheritance chains for components.
     *
     * Example:
     *
     * import { isRequired, checkRequired } from '../requiredInput';
     *
     *  export class MyComp implements OnInit {
     *
     *    // Chain id paramter we check for from the wallet
     *    @Input()
     *    @isRequired
     *    requiredChainId: number;
     *
     *    ngOnInit(): void {
     *      checkRequired(this);
     *    }
     *  }
     *
     * @param target Object given by the TypeScript decorator
     * @param prop Property name from the TypeScript decorator
     */
    export function isRequired(target: any, prop: string) {
      // Maintain a global table which components require which inputs
      const className = target.constructor.name;
      requiredInputs[className] = requiredInputs[className] || [];
      requiredInputs[className].push(prop);
      // console.log(className, prop, requiredInputs[className]);
    }
    
    /**
     * Check that all required inputs are filled.
     */
    export function checkRequired(component: any) {
    
      let className = component.constructor.name;
      let nextParent = Object.getPrototypeOf(component);
    
      // Walk through the parent class chain
      while(className != "Object") {
    
        for(let prop of (requiredInputs[className] || [])) {
          const val = component[prop];
          if(val === null || val === undefined) {
            console.error(component.constructor.name, prop, "is required, but was not provided, actual value is", val);
          }
        }
    
        className = nextParent.constructor.name;
        nextParent = Object.getPrototypeOf(nextParent);
        // console.log("Checking", component, className);
      }
    }
    
    
    

提交回复
热议问题