reactivos - validar campos con angular 2
Restablecer un formulario en Angular 2 después de enviar (10)
Soy consciente de que Angular 2 actualmente carece de una forma de restablecer fácilmente un formulario a un estado prístino. Hurgando, he encontrado una solución como la siguiente que restablece los campos del formulario.
Se ha sugerido que necesito abandonar el grupo de control y crear uno nuevo para reconstruir el formulario como prístino. Tengo dificultades para encontrar la mejor manera de hacerlo. Sé que necesito envolver el formulario dentro de una función, pero me encuentro con errores al hacerlo dentro del constructor.
¿Cuál sería la mejor manera de reconstruir el grupo de control para restablecer completamente el formulario?
class App {
name: Control;
username: Control;
email: Control;
form: ControlGroup;
constructor(private builder: FormBuilder) {
this.name = new Control('''', Validators.required);
this.email = new Control('''', Validators.required);
this.username = new Control('''', Validators.required);
this.form = builder.group({
name: this.name,
email: this.email,
username: this.username
});
}
onSubmit(value: any): void {
// code that happens when form is submitted
// then reset the form
this.reset();
}
reset() {
for (let name in this.form.controls) {
this.form.controls[name].updateValue('''');
this.form.controls[name].setErrors(null);
}
}
}
Cuando estaba leyendo la guía básica de Angular sobre formularios, y llegué a la sección de reinicio de formularios, me sorprendió mucho cuando leí lo siguiente en relación con la solución que ofrecen.
Esta es una solución temporal mientras esperamos una función de restablecimiento de formulario adecuada.
Personalmente, no he probado si la solución que proporcionaron funciona (supongo que sí), pero creo que no está bien, y que debe haber una mejor manera de abordar el problema.
De acuerdo con la API FormGroup (que está marcada como estable) ya existe un método de ''restablecimiento''.
Intenté lo siguiente. En mi archivo template.html tuve
<form (ngSubmit)="register(); registrationForm.reset();" #registrationForm="ngForm">
...
</form>
Observe que en el elemento de formulario, he inicializado una variable de referencia de plantilla ''RegistrationForm'' y la inicialicé en la Directiva ngForm , que "gobierna el formulario como un todo". Esto me dio acceso a los métodos y atributos del FormGroup que gobierna, incluido el método reset ().
Al vincular esta llamada de método al evento ngSubmit como se muestra arriba, restablezca el formulario (incluidos los estados prístino, sucio, modelo, etc.) después de que se complete el método register (). Para una demostración, esto está bien, sin embargo, no es muy útil para aplicaciones del mundo real.
Imagine que el método register () realiza una llamada al servidor. Queremos restablecer el formulario cuando sepamos que el servidor respondió que todo está bien. La actualización del código a los siguientes abastece a este escenario.
En mi archivo template.html:
<form (ngSubmit)="register(registrationForm);" #registrationForm="ngForm">
...
</form>
Y en mi archivo component.ts:
@Component({
...
})
export class RegistrationComponent {
register(form: FormGroup) {
...
// Somewhere within the asynchronous call resolve function
form.reset();
}
}
Pasar la referencia de ''RegistrationForm'' al método nos permitiría llamar al método reset en el punto de ejecución que queramos.
Espero que esto te ayude de alguna manera. :)
Nota : este enfoque se basa en Angular 2.0.0-rc.5
Estoy usando formas reactivas en angular 4 y este enfoque funciona para mí:
this.profileEditForm.reset(this.profileEditForm.value);
vea restablecer los indicadores de formulario en el documento Fundamentals
No sé si estoy en el camino correcto, pero lo hice funcionar en ng 2.4.8 con el siguiente formulario / enviar etiquetas:
<form #heroForm="ngForm" (ngSubmit)="add(newHero); heroForm.reset()">
<!-- place your input stuff here -->
<button type="submit" class="btn btn-default" [disabled]="!heroForm.valid">Add hero</button>
Parece hacer el truco y establece los campos del formulario en "prístino" nuevamente.
Para Angular 2 Final, ahora tenemos una nueva API que restablece limpiamente el formulario:
@Component({...})
class App {
form: FormGroup;
...
reset() {
this.form.reset();
}
}
Esta API no solo restablece los valores del formulario, sino que también establece los estados del campo del formulario en
ng-pristine
y
ng-untouched
.
Si llama solo a la función
reset()
, los controles de formulario no se establecerán en estado prístino.
Los documentos android.io tienen una solución para este problema.
componente.ts
active = true;
resetForm() {
this.form.reset();
this.active = false;
setTimeout(() => this.active = true, 0);
}
componente.html
<form *ngIf="active">
Utilicé en un caso similar la respuesta de Günter Zöchbauer, y fue perfecta para mí, moviendo la creación del formulario a una función y llamándola desde ngOnInit ().
Por ejemplo, así lo hice, incluida la inicialización de campos:
ngOnInit() {
// initializing the form model here
this.createForm();
}
createForm() {
let EMAIL_REGEXP = /^[^@]+@([^@/.]+/.)+[^@/.]+$/i; // here just to add something more, useful too
this.userForm = new FormGroup({
name: new FormControl('''', [Validators.required, Validators.minLength(3)]),
city: new FormControl(''''),
email: new FormControl(null, Validators.pattern(EMAIL_REGEXP))
});
this.initializeFormValues();
}
initializeFormValues() {
const people = {
name: '''',
city: ''Rio de Janeiro'', // Only for demonstration
email: ''''
};
(<FormGroup>this.userForm).setValue(people, { onlySelf: true });
}
resetForm() {
this.createForm();
this.submitted = false;
}
Agregué un botón al formulario para un reinicio inteligente (con la inicialización de los campos):
En el archivo HTML (o plantilla en línea):
<button type="button" [disabled]="userForm.pristine" (click)="resetForm()">Reset</button>
Después de cargar el formulario por primera vez o después de hacer clic en el botón de reinicio tenemos el siguiente estado:
FORM pristine: true
FORM valid: false (because I have required a field)
FORM submitted: false
Name pristine: true
City pristine: true
Email pristine: true
¡Y todas las inicializaciones de campo que un simple form.reset () no crea para nosotros! :-)
Utilice
NgForm
.resetForm()
de
.reset()
lugar de
.reset()
porque es el método que está oficialmente documentado en la API pública de
NgForm
.
(Ref. [
1
])
<form (ngSubmit)="mySubmitHandler(); myNgForm.resetForm()" #myNgForm="ngForm">
El método
.resetForm()
restablecerá el
NgForm
de
FormGroup
y establecerá su indicador de
submit
en
false
(Ver [
2
]).
Probado en @angular versiones 2.4.8 y 4.0.0-rc3
Utilice el siguiente formato, funciona perfectamente para mí ... He comprobado muchas formas pero funciona perfectamente.
<form (ngSubmit)="mySubmitHandler(); myNgForm.resetForm()" #myNgForm="ngForm"> .... </form>
si alguien quiere borrar solo un control de formulario particular, uno puede usar
formSubmit(){
this.formName.patchValue({
formControlName:''''
//or if one wants to change formControl to a different value on submit
formControlName:''form value after submission''
});
}
> = RC.6
Admite restablecer formularios y mantener un estado
submitted
.
console.log(this.form.submitted);
this.form.reset()
o
this.form = new FormGroup()...;
actualización importante
Para establecer los controles del formulario en un estado cuando se crea el formulario, como los validadores, son necesarias algunas medidas adicionales
En la parte de vista del formulario (html) agregue un
*ngIf
para mostrar u ocultar el formulario
<form *ngIf="showForm"
En el lado componente del formulario (* .ts) haga esto
showForm:boolean = true;
onSubmit(value:any):void {
this.showForm = false;
setTimeout(() => {
this.reset()
this.showForm = true;
});
}
Aquí hay un ejemplo más detallado:
export class CreateParkingComponent implements OnInit {
createParkingForm: FormGroup ;
showForm = true ;
constructor(
private formBuilder: FormBuilder,
private parkingService: ParkingService,
private snackBar: MatSnackBar) {
this.prepareForm() ;
}
prepareForm() {
this.createParkingForm = this.formBuilder.group({
''name'': ['''', Validators.compose([Validators.required, Validators.minLength(5)])],
''company'': ['''', Validators.minLength(5)],
''city'': ['''', Validators.required],
''address'': ['''', Validators.compose([Validators.required, Validators.minLength(10)])],
''latitude'': [''''],
''longitude'': [''''],
''phone'': ['''', Validators.compose([Validators.required, Validators.minLength(7)])],
''pictureUrl'': [''''],
// process the 3 input values of the maxCapacity''
''pricingText'': ['''', Validators.compose([Validators.required, Validators.minLength(10)])],
''ceilingType'': ['''', Validators.required],
});
}
ngOnInit() {
}
resetForm(form: FormGroup) {
this.prepareForm();
}
createParkingSubmit() {
// Hide the form while the submit is done
this.showForm = false ;
// In this case call the backend and react to the success or fail answer
this.parkingService.create(p).subscribe(
response => {
console.log(response);
this.snackBar.open(''Parqueadero creado'', ''X'', {duration: 3000});
setTimeout(() => {
//reset the form and show it again
this.prepareForm();
this.showForm = true;
});
}
, error => {
console.log(error);
this.showForm = true ;
this.snackBar.open(''ERROR: al crear Parqueadero:'' + error.message);
}
);
}
}
original <= RC.5 Simplemente mueva el código que crea el formulario a un método y vuelva a llamarlo después de manejar el envío:
@Component({
selector: ''form-component'',
template: `
<form (ngSubmit)="onSubmit($event)" [ngFormModel]="form">
<input type="test" ngControl="name">
<input type="test" ngControl="email">
<input type="test" ngControl="username">
<button type="submit">submit</button>
</form>
<div>name: {{name.value}}</div>
<div>email: {{email.value}}</div>
<div>username: {{username.value}}</div>
`
})
class FormComponent {
name:Control;
username:Control;
email:Control;
form:ControlGroup;
constructor(private builder:FormBuilder) {
this.createForm();
}
createForm() {
this.name = new Control('''', Validators.required);
this.email = new Control('''', Validators.required);
this.username = new Control('''', Validators.required);
this.form = this.builder.group({
name: this.name,
email: this.email,
username: this.username
});
}
onSubmit(value:any):void {
// code that happens when form is submitted
// then reset the form
this.reset();
}
reset() {
this.createForm();
}
}