paso pasar parametros page entre directivas comunicacion componentes change typescript angular

pasar - ¿Cómo cambiar el elemento HTML de solo lectura y el atributo requerido en Angular2 Typescript?



pasar parametros entre componentes angular 4 (3)

Para algunos de mis componentes me gustaría cambiar el campo de entrada de solo lectura y los atributos requeridos de ida y vuelta.

Me las arreglé para obtener un código en ejecución, que los cambia a ambos a pedido, pero el problema es que funciona solo para lectura, pero parece que no está funcionando en forma requerida: aunque el atributo del elemento cambia a Angular2 requerido aún piensa que fieldCtrl es válido.

Aquí está mi plunker, donde ilustré este problema: https://plnkr.co/edit/Yq2RDzUJjLPgReIgSBAO?p=preview

//our root app component import {Component} from ''angular2/core'' @Component({ selector: ''my-app'', providers: [], template: ` <div> <form #f="ngForm"> <button type="button" (click)="toggleReadOnly()">Change readonly!</button> <button type="button" (click)="toggleRequired()">Change required!</button> <input id="field" [(ngModel)]="field" ngControl="fieldCtrl" #fieldCtrl="ngForm"/> {{fieldCtrl.valid}} </form> </div> `, directives: [] }) export class App { constructor() { this.name = ''Angular2'' } toggleRequired(){ this.isRequired = !this.isRequired; var fieldElement = <HTMLInputElement>document.getElementById(''field''); if (this.isRequired){ fieldElement.required = true; this.field = "it''s required now"; } else{ fieldElement.required = false; this.field = "can leave it blank"; } } toggleReadOnly(){ this.isReadOnly = !this.isReadOnly; var fieldElement = <HTMLInputElement>document.getElementById(''field''); if (this.isReadOnly){ fieldElement.readOnly = true; this.field = "it''s readonly now"; } else{ fieldElement.readOnly = false; this.field = "feel free to edit"; } } private isReadOnly:boolean=false; private field:string = "feel free to edit"; private isRequired:boolean=false; }

ACTUALIZACIÓN: intentado método sugerido

[required]="isRequired" [readonly]="isReadOnly"

Y funciona como un hechizo para lectura solo, y para requerido = verdadero, pero ya no puedo desactivar el atributo requerido; muestra que el campo vacío no es válido, aunque ya no es necesario.

Plunker actualizado: https://plnkr.co/edit/6LvMqFzXHaLlV8fHbdOE

ACTUALIZACIÓN2: Intentado método sugerido

[required]="isRequired ? true : null"

Sí agrega / elimina el atributo requerido del elemento por demanda, sin embargo, la propiedad válida del controlador de campo muestra falso para el campo vacío que no es obligatorio.

¿Cuál sería la forma correcta de cambiar el atributo requerido en Angular2 Typescript?


Para que los atributos enlazados se eliminen, se deben establecer en nulo. Hubo una discusión para cambiarlo para eliminarlo en falso, pero se rechazó, al menos por ahora.

[required]="isRequired ? '''' : null"

o

[required]="isRequired ? ''required'' : null"

Su Plunker produce un error debido a que falta [] alrededor de ngControl .

Vea también este Plunker para un ejemplo de trabajo

Vea también los comentarios de Deilan a continuación.


Parece que ya tiene una respuesta para agregar / eliminar el atributo de solo lectura. Para el atributo requerido, sugiero crear un servicio para realizar un seguimiento del estado habilitado / deshabilitado del validador, y luego aprovechar el servicio cuando se vincula a sus controles de validación.

Validador del estado

Esta clase es responsable de realizar un seguimiento del validador y su estado habilitado / deshabilitado.

export class StateValidator { public enabled: boolean = true; validator: (control: Control) => { [key: string]: boolean }; constructor(validator: (control: Control) => { [key: string]: boolean }, enabled: boolean) { this.enabled = enabled; this.validator = validator; } enable() { this.enabled = true; } disable() { this.enabled = false; } toggle() { this.enabled = !this.enabled; } get() { return (control: Control) => { if (this.enabled) return this.validator(control); return null; } } }

Tiene métodos para habilitar, deshabilitar o alternar el validador; y también un método de get que devuelve una nueva función de validador, que cuando se invoca llamará a la función de validador subyacente si el validador está habilitado, o devolverá el valor nulo cuando el validador no esté habilitado.

Servicio de Validación

Esta clase es un servicio de singleton responsable de registrar los validadores por clave y los métodos compatibles para habilitar, deshabilitar o alternar un validador en función de esa clave.

export class ValidationService { validators: { [key: string]: StateValidator } = {}; register(key: string, validator: Function): Function { var stateValidator = new StateValidator(<(control: Control) => { [key: string]: boolean }>validator, true); this.validators[key] = stateValidator; return stateValidator.get(); } enable(key: string) { this.validators[key].enable(); } disable(key: string) { this.validators[key].disable(); } toggle(key: string) { this.validators[key].toggle(); } list() { var l = []; for (var key in this.validators) { if (this.validators.hasOwnProperty(key)) { l.push({ key: key, value: this.validators[key].enabled }); } } return l; } }

El servicio también tiene una función de list para devolver una lista de pares clave / valor donde la clave representa la clave del validador registrado, y el valor es un indicador booleano que representa el estado habilitado del validador.

Componente

Para usar el ValidationService , registre el servicio con el inyector raíz durante el arranque:

bootstrap(AppComponent, [ValidationService]);

O registre el servicio con el inyector de nivel de componente:

@Component({ selector: ''app'', providers: [ValidationService], ... })

Luego inyecte el servicio en el constructor de su componente:

export class AppComponent { form: ControlGroup; constructor(public validationService:ValidationService) { ... } }

A continuación, enlace a los controles de validación como lo haría normalmente, excepto que use ValidationService para registrarse y devolver el validador de estado:

new Control('''', validationService.register(''required'', Validators.required));

Una de las mejores cosas de esta solución es que puede componer y mezclar fácilmente validadores de estado con otros validadores integrados o personalizados:

this.form = new ControlGroup({ name: new Control(''hello'', Validators.compose([ validationService.register(''required'', Validators.required), validationService.register(''minlength'', Validators.minLength(4)), Validators.maxLength(10)])) });

Activar el validador

Utilice el servicio para cambiar el estado del validador:

validationService.toggle(''required'');

Este es un ejemplo de cómo enlazar a la lista de validadores de estado en una tabla, y conectar la función de alternar a un evento de clic de botón:

<table> <tr> <td>Validator</td> <td>Is Enabled?</td> <td></td> </tr> <tr *ngFor="#v of validationService.list()"> <td>{{v.key}}</td> <td>{{v.value }}</td> <td><button (click)="validationService.toggle(v.key)">Toggle</button></td> </tr> </table>

Demo plnkr


Una solución alternativa que utilizo:

import {Directive, ElementRef, Input} from ''@angular/core''; @Directive({ selector: ''[symToggleRequired]'' }) export class ToggleRequiredDirective { @Input() public set symToggleRequired(condition: boolean) { if (condition) { (<HTMLElement>this.element.nativeElement).setAttribute(''required'', ''true''); } else { (<HTMLElement>this.element.nativeElement).removeAttribute("required"); } } constructor( private element: ElementRef ) { } }

Use esta directiva en un elemento html para eliminar o agregar el atributo requerido:

<input [symToggleRequired]=''FlagPropertyOfYourComponent''>