javascript - 如何将步进功能添加到 ArrayForm?
问题描述
我正在使用 Angular,我有一个内部有动态 ArrayForm 的表单,
我已经创建了一个有步骤的函数,但是当我添加时,下面会创建另一个 FormArray,这会破坏我的应用程序
我想要的是 ArrayForm 保持相同的位置,下面不要相信
<h2> Registro de Usuario </h2>
<form (submit)="submit()" [formGroup]="registerForm">
<div class="form-group">
<label for="username">Username</label>
<input type="text" class="form-control" formControlName="username">
<div *ngIf="username.invalid && (username.dirty || username.touched)" class="alert alert-danger">
<div *ngIf="username.errors.required">
El nombre de usuario es requerido
</div>
<div *ngIf="username.errors.usernameUnico">
Ese nombre de usuario ya está en uso
</div>
</div>
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" class="form-control" formControlName="password">
<div *ngIf="password.invalid && (password.dirty || password.touched)" class="alert alert-danger">
<div *ngIf="password.errors.required">
El password es requerido
</div>
<div *ngIf="password.errors.minlength">
La longitud mínima del password es 4 caracteres
</div>
<div *ngIf="password.errors.passwordValidation">
{{password.errors.passwordValidation.message}}
</div>
</div>
</div>
<div class="form-group">
<label for="suscripcion">Escoja el tipo de suscripción</label>
<select class="form-control" id="suscripcion" name="suscripcion" formControlName="suscripcion">
<option *ngFor="let suscripcion of suscripciones" [value]="suscripcion.value">{{suscripcion.text}}</option>
</select>
</div>
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" formControlName="promociones">
<label class="form-check-label" for="promociones">Deseo recibir promociones</label>
</div>
<div class="form-group">
<div id="numberVariables" #numberVariables class="card p-3">
</div>
</div>
<div formArrayName="telefonos" *ngFor="let telefono of telefonos.controls; let i = index">
<div [formGroupName]="i">
<div class="form-group row mt-2">
<label class="col-md-1 mt-2" [attr.for]="'telefono' + i">Teléfono</label>
<div class="col-md-3">
<input type="text" [attr.id]="'telefono' + i" class="form-control" formControlName="telefono">
</div>
<label class="col-md-1 mt-2" [attr.for]="'descripcion' + i">Descripción</label>
<div class="col-md-5" mt-2>
<input type="text" [attr.id]="'descripcion' + i" class="form-control" formControlName="descripcion">
</div>
<div class="col-md-2 mt-2" >
<span class="material-icons deleteBtn" (click)="removerTelefono(i)">
delete
</span>
</div>
</div>
<div class="row">
<div class="col-md-12 mt-2">
<mat-form-field appearance="legacy">
<mat-label [attr.for]="'company' + i">Seleccione valor</mat-label>
<mat-select formControlName="company" (selectionChange)="filterFriends($event)">
<mat-option [attr.id]="'company' + i" *ngFor="let chuy of variablesCombo" [value]="chuy">
{{chuy.company}}
</mat-option>
</mat-select>
</mat-form-field>
</div>
<div class="row">
<div class="listVariables mt-3">
<mat-list-item>
<mat-selection-list multiple formControlName="friends">
<mat-list-option *ngIf="flagFriends" checkboxPosition="before" #allSelected
(click)="seleccionarChecks()" [value]="0">TODO
</mat-list-option>
<mat-list-option checkboxPosition="before" *ngFor="let friend of friends"
[value]="friend" (click)="seleccionarCheck(allSelected.viewValue)">
{{friend.name}}
</mat-list-option>
</mat-selection-list>
</mat-list-item>
</div>
</div>
</div>
</div>
</div>
<div class="row">
<div class="col-12 mt-3">
<button type="submit" class="btn btn-success" [disabled]="registerForm.invalid">Enviar</button>
<button type="button" class="btn btn-default" (click)="refrescar()">Refrescar</button>
</div>
</div>
</form>
ts:
@ViewChild('numberVariables', {static: false}) numberVariables: ElementRef;
@ViewChild('allSelected', {static: false}) private allSelected: MatOption;
viewNumber: number;
data: string = 'add';
numberVariable: Array<any> = [1];
variablesCombo: Array<any> = [];
friends: Array<any> = [];
flagFriends:boolean = false;
constructor(private formBuilder: FormBuilder,
private usernameUnicoService: UsernameUnicoService,
private renderer: Renderer2,
private eventManager: EventManager,
private toastr: ToastrService,
private service: WebApiService) {
}
get username() {
return this.registerForm.get('username');
}
get password() {
return this.registerForm.get('password');
}
get telefonos() {
return this.registerForm.get('telefonos') as FormArray;
}
registerForm = this.formBuilder.group({
username: ['', {
validators: [Validators.required],
asyncValidators: [this.usernameUnicoService.validate.bind(this.usernameUnicoService)],
updateOn: 'blur'
}],
password: ['', {
validators: [Validators.required, Validators.minLength(4), passwordValidation()]
}],
suscripcion: [Suscripcion.Basica],
promociones: [true],
telefonos: this.formBuilder.array([])
});
suscripciones: any[] = [];
ngAfterContentInit(): void {
console.log("afterinit");
setTimeout(() => {
this.dibujarCirculo(1);
this.agregarTelefono();
this.obtenerValores();
}, 1000);
}
ngOnInit() {
for (let item in Suscripcion) {
if (isNaN(Number(item))) {
this.suscripciones.push({text: item, value: Suscripcion[item]});
}
}
}
agregarTelefono() {
const telefonoFormGroup = this.formBuilder.group({
telefono: '',
descripcion: '',
company:'',
friends:''
});
this.telefonos.push(telefonoFormGroup);
}
removerTelefono(indice: number) {
this.telefonos.removeAt(indice);
this._deleteElement(indice)
}
submit() {
if (!this.registerForm.valid) {
alert('Alguna regla de validación no se está cumpliendo');
return;
}
console.log(this.registerForm.value);
}
refrescar() {
this.registerForm.patchValue({
username: '',
password: '',
suscripcion: Suscripcion.Basica,
promociones: true
});
this.telefonos.controls.splice(0, this.telefonos.length);
this.agregarTelefono();
}
dibujarCirculo(num) {
this.viewNumber = num;
let variablesCount = this.numberVariable;
let variablesRef = this.numberVariables;
variablesRef.nativeElement.innerHTML = "";
if (variablesCount.length === 0) {
variablesCount.push(1);
}
for (let i = 0; i < variablesCount.length; i++) {
if (i > 0) {
const span: any = this.renderer.createElement('span');
this.renderer.addClass(span, "lineCircle");
let line = this.renderer.createText("__");
this.renderer.appendChild(span, line);
if (variablesCount[i] <= num) {
span.style.borderColor = "#2A86CA";
span.style.color = "#2A86CA";
}
this.renderer.appendChild(variablesRef.nativeElement, span);
}
const span: any = this.renderer.createElement('span');
span.classList.add("numberCircle");
let number = this.renderer.createText(variablesCount[i]);
this.renderer.appendChild(span, number);
if (variablesCount[i] <= num) {
span.style.borderColor = "#2A86CA";
span.style.color = "#2A86CA";
}
this.eventManager.addEventListener(span, 'click', (ev) => this.selectNumber(ev));
this.renderer.appendChild(variablesRef.nativeElement, span);
}
const span: any = this.renderer.createElement('span');
this.renderer.addClass(span, "lineCircle");
if (this.data !== "ver") {
let line = this.renderer.createText("__");
this.renderer.appendChild(span, line);
}
this.renderer.appendChild(variablesRef.nativeElement, span);
if (this.data !== "ver") {
const span: any = this.renderer.createElement('span');
this.renderer.addClass(span, "numberCircle");
let signo = this.renderer.createText("+");
this.renderer.appendChild(span, signo);
this.eventManager.addEventListener(span, 'click', (ev, i) => this.crearNuevoCirculo());
this.renderer.appendChild(variablesRef.nativeElement, span);
}
}
selectNumber(ev: any) {
this.dibujarCirculo(ev.target.innerText)
}
crearNuevoCirculo() {
this.numberVariable.push(this.numberVariable.length + 1);
this.dibujarCirculo(this.numberVariable.length);
this.agregarTelefono();
}
_deleteElement(element) {
let el;
let num = 0;
for (el in this.telefonos) {
num++;
if (el === element) {
break;
}
}
if (num === Object.keys(this.telefonos).length) {
num--;
if (num < 1) {
num = 1;
}
}
delete this.telefonos[element];
this.numberVariable = this.numberVariable.slice(0, -1);
this.toastr.success("Variable Eliminada Correctamente!");
this.dibujarCirculo(num);
}
obtenerValores(){
this.service.obtenerFake()
.subscribe(data =>{
this.variablesCombo = data;
console.log(this.variablesCombo);
})
}
filterFriends(data) {
this.friends = data.value.friends.reduce((a, b) => a = a.concat(b), []);
this.flagFriends =true
console.log("list of friends", this.friends);
}
seleccionarChecks() {
if (this.allSelected.selected) {
this.registerForm.controls.telefonos
.patchValue([...this.friends.map(item => item.id), 0]);
} else {
this.registerForm.controls.friends.patchValue([]);
}
}
seleccionarCheck(data) {
if (this.allSelected.selected) {
this.allSelected.deselect();
return false;
}
if (this.registerForm.controls.telefonos.value.length == this.friends.length){
this.allSelected.select();
}
}
我已经看到有角度的材料有步骤,但我需要它们是我在这里拥有的数字序列
解决方案
推荐阅读
- zsh - 将我的 shell 更新为 zsh,命令提示符现在以 % 结尾
- loops - Python 范围和循环令人困惑
- unity3d - 使用 fastlane 为 iOS 构建 Unity 游戏失败,缺少 USYM_UPLOAD_AUTH_TOKEN
- java - 双击时程序无法正常执行。“发生 JNI 错误,请检查您的安装并重试。”
- bash - 无法使用带有 docker exec 的 psql 命令行从文件运行查询
- c# - 如何停止自动生成我引用的 dll 文件?(视觉工作室)
- python - 无法解决 ModuleNotFoundError
- sql-server - 有没有办法填补没有 ReviewType 出现日期占位符和 0 次出现的日期空白
- google-cloud-platform - 无法获得可读的编码字符串
- django - 如何将主键存储在会话变量中