Växla FormControl i vy med Formbuilder Typescript med Angular 8
Hur tar jag bort element från en HTML DOM-vy med NgIf med Typescript, inte html? Letar efter liknande syntax.
Föredrar att iterera genom en Array i TypeScript, och ta bort objekt från vyn, istället för att omsluta alla 20 formkontroller med NgIf, verkar ganska repetitivt.
För närvarande använder jag Formbuilder, inte FormArray. Denna länk sätter stilen display none, vilket enligt vad jag har läst inte är en ideal praxis i Angular. Är det sant?
Angular 2 -> hur man döljer kontroller med FormGroup
Vi har en exkluderingsarray och föredrar att inaktivera med foreach i Typescript
Kanske något liknande detta?
Detta inaktiverar bara fältet, visas fortfarande i HTML-visning
Object.keys(this.customerForm.controls).forEach(key => {
if (this.excludeFormControlArray.indexOf(key) >= 0) {
this.customerForm.get(key).disable; // This only disables the field, still shows in html View
this.customerForm = this.formBuilder.group({
'firstName': [null, [Validators.maxLength(50), PhoneNumberValidator]],
'phoneNumber': [null, [Validators.maxLength(50), PhoneNumberValidator]],
'streetName': [null, [Validators.maxLength(50), PhoneNumberValidator]],
'emailAddress': [null, [Validators.maxLength(50), Validators.email]],
'city': [null, [Validators.required, Validators.maxLength(200)]],
'state': [null, [Validators.maxLength(200)]],
'zip':[null,[Validators.maxLength(200)]]
});
HTML
//försöker förhindra att varje omsluts med ngIf, objekt placeras på en speciell plats på sidan, på grund av UX-wireframe-specifikationer, NgFor var inte helt möjligt, html/css-vyn är mycket mer komplicerad än detta,
<div class = "row">
<app-input-textbox formControlName = "firstName"></app-input-textbox>
<div class = "row">
<div class = "column">
<app-input-textbox formControlName = "emailAddress"></app-input-textbox>
</div>
<div class = "test">
<app-input-textbox formControlName = "state"></app-input-textbox>
<app-input-textbox formControlName = "zip"></app-input-textbox>
</div>
Svar #1
Jag ser att du vill skapa en "app-input". Mitt förslag är att app-input injicerar FormGroupDirective i konstruktorn och använder direkt [formControl] se stackblitz
@Component({
selector: 'app-input',
template: `
<ng-container *ngIf="control && control.enabled">
{{label}}
<input [formControl]="control">
</ng-container>
`
})
export class HelloComponent {
constructor( @Optional() @Host() private form:FormGroupDirective){}
control:FormControl
@Input() set name(value)
{
this.control=this.form?this.form.form.get(value) as FormControl:null
}
@Input() label: string;
}
Detta gör att vi har ett formulär som
<form [formGroup]="formGroup">
<app-input name="one" label="One"></app-input>
<app-input name="two" label="Two"></app-input>
</form>
Om vi vill lägga till fel kan vi förbättra appens inmatning, använda en inmatning och en funktion för att få det första felet bland felen
@Input() errors:any={} //see that, by defect it's an empty object
getError()
{
for (let key of Object.keys(this.errors))
{
if (this.control.hasError(key))
return this.errors[key]
}
}
Och lägg till något liknande i mallen
<div *ngIf="control.touched">
{{getError()}}
</div>
Vår huvudapp blir som, t.ex.
<form [formGroup]="formGroup">
<app-input name="one" label="One" [errors]="{required:'One is required'}"></app-input>
<app-input name="two" label="Two"></app-input>
</form>
Tja, det här är bara ett exempel, jag hoppas att detta hjälper dig
Svar #2
Skapade en stackblitz för dig.
Här använder jag en egen modell (array) för att rendera fälten:
<h1>My dynamic form</h1>
<form [formGroup]="formGroup">
<div *ngFor="let input of inputList">
<label>{{ input.label }}</label>
<input type="{{ input.type }}" formControlName="{{ input.formControlName }}">
<span (click)="removeInputField(input)">Remove</span>
</div>
<div>
<button type="button" (click)="addInputField()">Add Input Field</button>
<button type="submit">Submit</button>
</div>
</form>
Och här är två metoder för att lägga till och ta bort kontroller:
addInputField() {
const formControlName = prompt("FormControlName input: ");
const inputType = prompt("Type input: ");
const label = prompt("Label input: ");
const inputData = {
inputType: inputType,
formControlName: formControlName,
label: label
};
this.inputList.push(inputData);
this.formGroup.addControl(
inputData.formControlName,
this.formBuilder.control("")
);
}
removeInputField(inputField: InputField) {
this.formGroup.removeControl(inputField.formControlName);
this.inputList = this.inputList.filter(field => field !== inputField);
}
Huvudsteget är att kalla på removeControl och addControl-metoderna.
I ditt fall bör du bara kalla på this.customerForm.removeControl(key).
