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 时单击它们。