example directivas create angular angular2-directives

directivas - Angular 2 hace @Input en directiva requerida



directivas angular 5 (4)

En Angular 1 podríamos hacer un atributo directivo requerido. ¿Cómo hacemos eso en Angular 2 con @Input? Los doctores no lo mencionan.

P.ej.

Component({ selector: ''my-dir'', template: ''<div></div>'' }) export class MyComponent { @Input() a:number; // Make this a required attribute. Throw an exception if it doesnt exist @Input() b:number; constructor(){ } }


Aquí está mi solución con getters / setters. En mi humilde opinión, esta es una solución mucho más elegante, ya que todo se hace en un solo lugar y esta solución no requiere la dependencia de OnInit .

Solución # 1

Component({ selector: ''my-dir'', template: ''<div></div>'' }) export class MyComponent { @Input() get a () { throw new Error(''Attribute "a" is required''); } set a (value: number) { Object.defineProperty(this, ''a'', { value, writable: true, configurable: true }); } }

Solución # 2 :

Se podría hacer aún más fácil con los decoradores. Por lo tanto, en su aplicación usted define un decorador como este:

function Required(target: object, propertyKey: string) { Object.defineProperty(target, propertyKey, { get () { throw new Error(`Attribute ${propertyKey} is required`); }, set (value) { Object.defineProperty(target, propertyKey, { value, writable: true, configurable: true }); }, }); }

Y más adelante en tu clase, solo necesitas marcar tu propiedad como se requiere así:

Component({ selector: ''my-dir'', template: ''<div></div>'' }) export class MyComponent { @Input() @Required a: number; }

Explicación :

Si el atributo a está definido, el establecedor de la propiedad a se anulará a sí mismo y se usará el valor pasado al atributo. De lo contrario, después del componente init, la primera vez que desee utilizar la propiedad a en su clase o plantilla, se generará un error.

Nota: los getters / setters funcionan bien dentro de los componentes / servicios de Angular, etc. y es seguro usarlos así. Pero tenga cuidado al utilizar este enfoque con clases puras fuera de Angular. El problema es cómo mecanografiado convierte getters / setters - se asignan a la propiedad de prototype de la clase. En este caso, mutamos la propiedad prototipo que será la misma para todas las instancias de clase. Significa que podemos conseguir algo como esto:

const instance1 = new ClassStub(); instance1.property = ''some value''; const instance2 = new ClassStub(); console.log(instance2.property); // ''some value''


Para mí, tuve que hacerlo de esta manera:

ngOnInit() { if(!this.hasOwnProperty(''a'') throw new Error("Attribute ''a'' is required"); }

Para tu información, si quieres requerir las directivas @Output, prueba esto:

export class MyComponent { @Output() myEvent = new EventEmitter(); // This a required event ngOnInit() { if(this.myEvent.observers.length === 0) throw new Error("Event ''myEvent'' is required"); } }


Puedes hacerlo así:

constructor() {} ngOnInit() { if (!this.a) throw new Error(); }


Verifique en ngOnInit() (las entradas aún no están establecidas cuando se ejecuta el constructor) si el atributo tiene un valor.

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

También puede verificar en ngOnChanges(changes) {...} si los valores no se establecieron en null . Consulte también https://angular.io/docs/ts/latest/api/core/OnChanges-interface.html