Angular - 按 Enter 键时输入被删除,因为调用 "delete" 函数,而不是预期的焦点
Angular - Inputs are being deleted on Enter press, as calling "delete" function, instead of intended focus
编辑:添加了一个stackblitz
我正在尝试让应用程序能够在按下回车键时在输入之间跳转,这样比单击它们更容易。我为第一个设置了 (keyup.enter)="keytab($event)"
,为第二个设置了 (keyup.enter)="addPeso()"
,因为它们是动态创建的,所以 "addPeso" 创建了一对新的输入。问题是,每次我按下回车键,每个输入都会被删除,就好像它在调用 deleteAllPesos 函数(生成 .clear())一样。我不明白为什么会这样。也许你能看到我看不到的东西。
ts:
import { Component, OnInit, HostListener } from "@angular/core";
import { resetFakeAsyncZone } from "@angular/core/testing";
import { Contenedor } from "../models/contenedor";
import { FormArray, FormBuilder } from "@angular/forms";
import { FormGroup, FormControl } from "@angular/forms";
@Component({
selector: "app-contenedores",
templateUrl: "./contenedores.component.html",
styleUrls: ["./contenedores.component.css"]
})
export class ContenedoresComponent implements OnInit {
public arrayprueba: Array<any>;
public JSONFormulario: any;
public maxArrayP: Array<number>;
public maxArrayN: Array<string>;
public pesos_ordenados: Array<any>;
public pesos1: Array<number>;
public pesos2: Array<number>;
public contenedor: Contenedor;
public contenedores: Array<Contenedor>;
public capacidad1: number;
public maxCasas: number;
public mcArray: Array<any>;
public inputsPeso: Array<number>;
public inputsNombre: Array<string>;
public dummyCounter: Array<number>;
public Pesos_de_un_contenedor: Array<any>;
public cap: number;
public formulario = this.fb.group({
capacidad: ["5"],
maxcasas: ["3"],
pesos: this.fb.array([
this.fb.group({
peso: this.fb.control(""),
nombre: this.fb.control("")
})
])
});
get pesos() {
return this.formulario.get("pesos") as FormArray;
}
constructor(private fb: FormBuilder) {
this.JSONFormulario = "";
this.maxArrayP = [];
this.maxArrayN = [];
this.inputsPeso = [];
this.dummyCounter = [];
this.inputsNombre = [];
this.pesos1 = [];
this.contenedor = new Contenedor();
this.contenedores = [];
this.capacidad1 = 24300;
this.maxCasas = 3;
this.Pesos_de_un_contenedor = [];
this.pesos_ordenados = [];
this.cap = this.formulario.controls.capacidad.value;
}
addPeso() {
this.pesos.push(
this.fb.group({
peso: this.fb.control(""),
nombre: this.fb.control("")
})
);
}
deleteAllPesos() {
this.pesos.clear();
this.showPesos();
}
deletePeso(este: number) {
this.pesos.removeAt(este);
this.showPesos();
}
@HostListener("document:keyup", ["$event"])
showPesos() {
this.pesos_ordenados = [];
this.contenedores = [];
for (var i = 0; i < this.pesos.controls.length; i++) {
if (this.pesos.at(i).value.peso) {
if(this.pesos.at(i).value.peso<= this.formulario.controls.capacidad.value){
this.pesos_ordenados[i] = {peso: this.pesos.at(i).value.peso,nombre: this.pesos.at(i).value.nombre};
}else{
this.pesos.at(i).value.peso
}
}
}
this.pesos_ordenados = this.pesos_ordenados.sort(function(a, b) {
return b.peso - a.peso;
});
this.CleanShowinConsole(this.pesos_ordenados);
if(this.pesos_ordenados[0]) console.log("EL FORMULARIO" + this.pesos_ordenados[0].peso);
/* for (var z = 0; z < this.pesos_ordenados.length; z++) {
this.maxArrayP = [];
this.maxArrayN = []; */
this.maxArrayP = [];
this.maxArrayN = [];
while (this.pesos_ordenados.length > 0) {
if(this.pesos_ordenados[0].peso){
if (Number(this.pesos_ordenados[0].peso) + Number(this.maxArrayP.reduce(function(a, b) {return Number(a) + Number(b);}, 0)) <= this.formulario.controls.capacidad.value)
{
this.maxArrayP.push(this.pesos_ordenados[0].peso);
this.maxArrayN.push(this.pesos_ordenados[0].nombre);
this.pesos_ordenados.shift();
if(this.pesos_ordenados.length<=0){
this.contenedor = new Contenedor(this.maxArrayP,this.maxArrayN,this.formulario.controls.capacidad.value);
this.contenedor.crearMapa(this.maxArrayP,this.maxArrayN);
this.contenedores.push(this.contenedor);
}
}else{
this.contenedor = new Contenedor(
this.maxArrayP,
this.maxArrayN,
this.formulario.controls.capacidad.value
);
this.contenedor.crearMapa(this.maxArrayP,this.maxArrayN);
this.contenedores.push(this.contenedor);
this.maxArrayP = [];
this.maxArrayN = [];
}
}
}
console.log("LISTA DE CONTENEDORES:");
for (let i = 0; i < this.contenedores.length; i++) {
console.log("CONTENEDOR" + i + ": " + this.contenedores[i].$pesos);
}
}
private CleanShowinConsole(arrayordenada: any) {
console.clear();
for (var i = 0; i < arrayordenada.length; i++) {
console.log(arrayordenada[i]);
}
}
keytab(event){
let element = event.srcElement.nextElementSibling; // get the sibling element
if(element == null) // check if its null
return;
else
element.focus(); // focus if not null
}
ngOnInit() {}
}
html
<div [className]="divformulario">
<img src="../../assets/img/logo.png" />
<form [formGroup]="formulario">
<div [className]="form - subconjunto - horizontal">
<mat-form-field style="width:4vw">
<mat-label>Capacidad</mat-label>
<input matInput type="number" formControlName="capacidad" />
</mat-form-field>
<mat-form-field style="width:4vw">
<mat-label>Máx.casas</mat-label>
<input matInput type="number" formControlName="maxcasas" />
</mat-form-field>
</div>
<div formArrayName="pesos">
<div [className]="form - subconjunto - horizontal">
<button mat-stroked-button color="primary" (click)="deleteAllPesos()">
<mat-icon>delete_sweep</mat-icon> Resetear
</button>
<button mat-flat-button color="primary" (click)="addPeso()">
<mat-icon>add</mat-icon> Añadir peso
</button>
</div>
<div
*ngFor="let peso of pesos.controls; let i = index"
[formGroupName]="i"
[className]="form - subconjunto - horizontal"
>
<mat-form-field>
<mat-label>Peso</mat-label>
<input
matInput
[style.color]="
pesos.at(i).get('peso').value > formulario.get('capacidad').value
? 'red'
: 'black'
"
type="number"
formControlName="peso"
autofocus
(keyup.enter)="keytab($event)"
/>
</mat-form-field>
<mat-form-field>
<mat-label>Casa</mat-label>
<input matInput type="text" formControlName="nombre" type="text" (keyup.enter)="addPeso()"/>
</mat-form-field>
<button mat-mini-fab color="primary" (click)="deletePeso(i)">
<mat-icon>delete_forever</mat-icon>
</button>
</div>
</div>
</form>
</div>
<div id="contenedores">
<div *ngFor="let contenedor of contenedores; let i = index">
<mat-card>
<mat-card-header>
<mat-card-title>Contenedor {{ i + 1 }}</mat-card-title>
<mat-card-subtitle>
LLeno: {{ contenedor.pesoTotal }} | Sobrante:
{{ contenedor.sobrante }}
</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<div *ngFor="let datos of contenedor.datos | keyvalue;">
{{datos.key}}{{datos.value}}
</div>
</mat-card-content>
</mat-card>
</div>
</div>
到处搜索后,我发现 github issue 声明了这种行为:
jonrimmer 于 2016 年 11 月 1 日发表评论
这是标准的 HTML 表单行为,与 Angular 无关。在聚焦的文本输入中按下回车键将单击表单中的第一个提交按钮。
避免它的一种方法是在表单中不要有任何提交按钮。在您的 plunker 中,将 type="button" 属性添加到每个按钮元素将防止在用户按下 enter 时单击它们。
编辑:添加了一个stackblitz
我正在尝试让应用程序能够在按下回车键时在输入之间跳转,这样比单击它们更容易。我为第一个设置了 (keyup.enter)="keytab($event)"
,为第二个设置了 (keyup.enter)="addPeso()"
,因为它们是动态创建的,所以 "addPeso" 创建了一对新的输入。问题是,每次我按下回车键,每个输入都会被删除,就好像它在调用 deleteAllPesos 函数(生成 .clear())一样。我不明白为什么会这样。也许你能看到我看不到的东西。
ts:
import { Component, OnInit, HostListener } from "@angular/core";
import { resetFakeAsyncZone } from "@angular/core/testing";
import { Contenedor } from "../models/contenedor";
import { FormArray, FormBuilder } from "@angular/forms";
import { FormGroup, FormControl } from "@angular/forms";
@Component({
selector: "app-contenedores",
templateUrl: "./contenedores.component.html",
styleUrls: ["./contenedores.component.css"]
})
export class ContenedoresComponent implements OnInit {
public arrayprueba: Array<any>;
public JSONFormulario: any;
public maxArrayP: Array<number>;
public maxArrayN: Array<string>;
public pesos_ordenados: Array<any>;
public pesos1: Array<number>;
public pesos2: Array<number>;
public contenedor: Contenedor;
public contenedores: Array<Contenedor>;
public capacidad1: number;
public maxCasas: number;
public mcArray: Array<any>;
public inputsPeso: Array<number>;
public inputsNombre: Array<string>;
public dummyCounter: Array<number>;
public Pesos_de_un_contenedor: Array<any>;
public cap: number;
public formulario = this.fb.group({
capacidad: ["5"],
maxcasas: ["3"],
pesos: this.fb.array([
this.fb.group({
peso: this.fb.control(""),
nombre: this.fb.control("")
})
])
});
get pesos() {
return this.formulario.get("pesos") as FormArray;
}
constructor(private fb: FormBuilder) {
this.JSONFormulario = "";
this.maxArrayP = [];
this.maxArrayN = [];
this.inputsPeso = [];
this.dummyCounter = [];
this.inputsNombre = [];
this.pesos1 = [];
this.contenedor = new Contenedor();
this.contenedores = [];
this.capacidad1 = 24300;
this.maxCasas = 3;
this.Pesos_de_un_contenedor = [];
this.pesos_ordenados = [];
this.cap = this.formulario.controls.capacidad.value;
}
addPeso() {
this.pesos.push(
this.fb.group({
peso: this.fb.control(""),
nombre: this.fb.control("")
})
);
}
deleteAllPesos() {
this.pesos.clear();
this.showPesos();
}
deletePeso(este: number) {
this.pesos.removeAt(este);
this.showPesos();
}
@HostListener("document:keyup", ["$event"])
showPesos() {
this.pesos_ordenados = [];
this.contenedores = [];
for (var i = 0; i < this.pesos.controls.length; i++) {
if (this.pesos.at(i).value.peso) {
if(this.pesos.at(i).value.peso<= this.formulario.controls.capacidad.value){
this.pesos_ordenados[i] = {peso: this.pesos.at(i).value.peso,nombre: this.pesos.at(i).value.nombre};
}else{
this.pesos.at(i).value.peso
}
}
}
this.pesos_ordenados = this.pesos_ordenados.sort(function(a, b) {
return b.peso - a.peso;
});
this.CleanShowinConsole(this.pesos_ordenados);
if(this.pesos_ordenados[0]) console.log("EL FORMULARIO" + this.pesos_ordenados[0].peso);
/* for (var z = 0; z < this.pesos_ordenados.length; z++) {
this.maxArrayP = [];
this.maxArrayN = []; */
this.maxArrayP = [];
this.maxArrayN = [];
while (this.pesos_ordenados.length > 0) {
if(this.pesos_ordenados[0].peso){
if (Number(this.pesos_ordenados[0].peso) + Number(this.maxArrayP.reduce(function(a, b) {return Number(a) + Number(b);}, 0)) <= this.formulario.controls.capacidad.value)
{
this.maxArrayP.push(this.pesos_ordenados[0].peso);
this.maxArrayN.push(this.pesos_ordenados[0].nombre);
this.pesos_ordenados.shift();
if(this.pesos_ordenados.length<=0){
this.contenedor = new Contenedor(this.maxArrayP,this.maxArrayN,this.formulario.controls.capacidad.value);
this.contenedor.crearMapa(this.maxArrayP,this.maxArrayN);
this.contenedores.push(this.contenedor);
}
}else{
this.contenedor = new Contenedor(
this.maxArrayP,
this.maxArrayN,
this.formulario.controls.capacidad.value
);
this.contenedor.crearMapa(this.maxArrayP,this.maxArrayN);
this.contenedores.push(this.contenedor);
this.maxArrayP = [];
this.maxArrayN = [];
}
}
}
console.log("LISTA DE CONTENEDORES:");
for (let i = 0; i < this.contenedores.length; i++) {
console.log("CONTENEDOR" + i + ": " + this.contenedores[i].$pesos);
}
}
private CleanShowinConsole(arrayordenada: any) {
console.clear();
for (var i = 0; i < arrayordenada.length; i++) {
console.log(arrayordenada[i]);
}
}
keytab(event){
let element = event.srcElement.nextElementSibling; // get the sibling element
if(element == null) // check if its null
return;
else
element.focus(); // focus if not null
}
ngOnInit() {}
}
html
<div [className]="divformulario">
<img src="../../assets/img/logo.png" />
<form [formGroup]="formulario">
<div [className]="form - subconjunto - horizontal">
<mat-form-field style="width:4vw">
<mat-label>Capacidad</mat-label>
<input matInput type="number" formControlName="capacidad" />
</mat-form-field>
<mat-form-field style="width:4vw">
<mat-label>Máx.casas</mat-label>
<input matInput type="number" formControlName="maxcasas" />
</mat-form-field>
</div>
<div formArrayName="pesos">
<div [className]="form - subconjunto - horizontal">
<button mat-stroked-button color="primary" (click)="deleteAllPesos()">
<mat-icon>delete_sweep</mat-icon> Resetear
</button>
<button mat-flat-button color="primary" (click)="addPeso()">
<mat-icon>add</mat-icon> Añadir peso
</button>
</div>
<div
*ngFor="let peso of pesos.controls; let i = index"
[formGroupName]="i"
[className]="form - subconjunto - horizontal"
>
<mat-form-field>
<mat-label>Peso</mat-label>
<input
matInput
[style.color]="
pesos.at(i).get('peso').value > formulario.get('capacidad').value
? 'red'
: 'black'
"
type="number"
formControlName="peso"
autofocus
(keyup.enter)="keytab($event)"
/>
</mat-form-field>
<mat-form-field>
<mat-label>Casa</mat-label>
<input matInput type="text" formControlName="nombre" type="text" (keyup.enter)="addPeso()"/>
</mat-form-field>
<button mat-mini-fab color="primary" (click)="deletePeso(i)">
<mat-icon>delete_forever</mat-icon>
</button>
</div>
</div>
</form>
</div>
<div id="contenedores">
<div *ngFor="let contenedor of contenedores; let i = index">
<mat-card>
<mat-card-header>
<mat-card-title>Contenedor {{ i + 1 }}</mat-card-title>
<mat-card-subtitle>
LLeno: {{ contenedor.pesoTotal }} | Sobrante:
{{ contenedor.sobrante }}
</mat-card-subtitle>
</mat-card-header>
<mat-card-content>
<div *ngFor="let datos of contenedor.datos | keyvalue;">
{{datos.key}}{{datos.value}}
</div>
</mat-card-content>
</mat-card>
</div>
</div>
到处搜索后,我发现 github issue 声明了这种行为:
jonrimmer 于 2016 年 11 月 1 日发表评论
这是标准的 HTML 表单行为,与 Angular 无关。在聚焦的文本输入中按下回车键将单击表单中的第一个提交按钮。 避免它的一种方法是在表单中不要有任何提交按钮。在您的 plunker 中,将 type="button" 属性添加到每个按钮元素将防止在用户按下 enter 时单击它们。