无法在 HTML 表单 text/password/number 输入字段中输入(使用 Unity WebGL 构建的网站)

Can't type in HTML form text/password/number input field (website with Unity WebGL build)

我们正在使用 Angular9 开发网站。 我们还在其中集成了 Unity3D WebGL 构建。 当我尝试在我的一个表单中的 text/password/number 输入字段 中输入内容时,它什么也没写,而且 该字段似乎也没有接收输入;另外,我将字段绑定到的变量不会用新值更新。 更奇怪的是:

这是我的登录表单中的代码(上面的 component.ts,下面的模板 HTML)

import { Component, OnInit } from '@angular/core';
import { AuthService } from '../auth.service'
import { first } from 'rxjs/operators';
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.less']
})
export class LoginComponent implements OnInit {

  email: string = "";
  password: string = "";

  returnUrl: string = "home";

  constructor(private router: Router, private route: ActivatedRoute, private authService: AuthService) { }

  ngOnInit(): void {
    let tmpReturnUrl = this.route.snapshot.queryParams["returnUrl"];
    if (tmpReturnUrl != undefined)
    {
      console.log("true");
      this.returnUrl = tmpReturnUrl;
    }
    else
      console.log("false");

    setInterval(() => {
      console.log("EMAIL: " + this.email);
    }, 1000);
  }

  onSubmit(){
    this.authService.login(this.email, this.password)
    .pipe(first())
    .subscribe(
      result => {
        console.log("CAIOAOAOAOOA");
        this.router.navigate([this.returnUrl]);
      },
      err => console.log(err)
    );
  }
}
<div class="card z-depth-5 w-50">
  <div class="card-body">
    <div class="card-title">Log in</div>
    <div class="card-text">
      <form #companyLoginForm="ngForm" (ngSubmit)="onSubmit()">
        <mat-form-field>
          <mat-label>Email: </mat-label>
          <input matInput required type="text" name="email" id="email" [(ngModel)]="email">
        </mat-form-field>
        <mat-form-field>
          <mat-label>Password: </mat-label>
          <input matInput required type="password" name="password" id="password" [(ngModel)]="password">
        </mat-form-field>
        <button type="submit" [disabled]="!companyLoginForm.form.valid">Login</button>
      </form>
      <a routerLink="/company-register">
        <button mdbBtn type="button" color="primary" class="relative waves-light">Sign Up</button>
      </a>
    </div>
  </div>
</div>

这里是另一种形式的代码,我还使用了 type="number"<select>(上面的 component.ts,下面的模板 HTML)

import { Component, OnInit, Output } from '@angular/core';
import { BlockFormService } from '../block-form.service';
import { BlockData } from '../blockCardData';
import { BlockUtilsService } from '../block-utils.service';
import { ApiService } from '../../core/api.service'
import { NgForm } from '@angular/forms';

@Component({
  selector: 'app-block-form',
  templateUrl: './block-form.component.html',
  styleUrls: ['./block-form.component.less']
})
export class BlockFormComponent implements OnInit {

  updateComplete : Boolean = false;
  materials : string[];
  products : string[];
  varieties : string[];
  nations : string[];
  // companies : {name: string, id: string}[] = [];
  company : string = "";
  colors : string[] = ["White", "Grey", "Black", "Brown", "Red", "Green", "Yellow", "Blue"];
  blockData : BlockData = {_id : "", blockId: "",  company: "", material: "", product: "",
                variety: "", color: "", nation: "", modelName : "", imagePreview : "",
                price: null, blockNumber: "",
                length: null, height: null, width: null,
                weight: null
  };
  imagePreview: File = null;
  zipFile: File = null;

  invalidUpload: boolean = false;

  constructor( private blockFormService: BlockFormService, public blockUtils: BlockUtilsService, private companiesUtils: ApiService )
  { }

  ngOnInit(): void {
    this.materials = this.blockUtils.getMaterials();
    this.colors = this.blockUtils.getColors();
    this.companiesUtils.getLoggedCompany().subscribe(companiesResult => {
      this.blockData.company = companiesResult._id;
      this.company = companiesResult.name;
    });
  }

  onImageSelected(event){
    console.log(event.target.files[0]);
    if (event.target.files[0].type === "image/png")
    {
      if (this.invalidUpload)
        this.invalidUpload = false;
      this.imagePreview = event.target.files[0];
    }
    else{
      if (!this.invalidUpload)
        this.invalidUpload = true;
      event.target.value = null;
    }
  }

  onMaterialSet(newMaterial): void{
    console.log("Material set");
    this.products = this.blockUtils.getProducts(newMaterial);
    //console.log(this.products);
    // if (this.products.length > 0)
    //   this.blockData.product = this.products[0];
    // else
      this.blockData.product = "";

    this.onProductSet(this.blockData.product);
  }

  onProductSet(newProduct): void{
    console.log("Product set");
    this.varieties = this.blockUtils.getVarieties(this.blockData.material, newProduct);
    // if (this.varieties.length > 0)
    //   this.blockData.variety = this.varieties[0];
    // else
    this.blockData.variety = "";

    this.nations = this.blockUtils.getNations(this.blockData.material, this.blockData.product);
    if (this.nations.length > 0)
      this.blockData.nation = this.nations[0];
    else
      this.blockData.nation = "";

    this.onVarietySet(this.blockData.variety);
  }

  onVarietySet(newVariety): void{
    console.log("Variety set");
    // this.nations = this.blockUtils.getNations(this.blockData.material, this.blockData.product);
    // if (this.nations.length > 0)
    //   this.blockData.nation = this.nations[0];
    // else
    //   this.blockData.nation = "";
  }

  onSubmit(blockForm : NgForm, imageField, zipField): void{
    this.blockFormService.sendBlock(this.blockData, this.imagePreview, this.zipFile)
    .subscribe(res => {
      console.log("Sent!");
      this.updateComplete = true;
    });

    this.blockData = {
      _id: "", blockId: "", company: "", material: "", product: "",
      variety: "", color: "", nation: "", modelName: "", imagePreview: "",
      price: null, blockNumber: "",
      length: null, height: null, width: null,
      weight: null
    };
    blockForm.resetForm();
    imageField.value = null;
    zipField.value = null;
    this.imagePreview = null;
    this.zipFile = null;
  }
}
<div class="form-group">


  <div class="text-center" *ngIf='updateComplete'>
    Block added successfuly
  </div>

  <form #blockForm="ngForm" (ngSubmit)="onSubmit(blockForm, imageField, zipField)">
    <div class="container">
      <div class="row">
        <div class="col-3">
          <mat-form-field>
            <mat-label>Company: </mat-label>
            <!-- <mat-select required [(ngModel)]="blockData.company" name="company-field"
              id="company-field">
              <mat-option selected [value]="company.id">{{company.name}}</mat-option>
            </mat-select> -->
            <input matInput disabled [value]="company" type="text" name="company-field" id="company-field">
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Material: </mat-label>
            <mat-select #matField required [(ngModel)]="blockData.material" name="kind-field"
              id="kind-field" (selectionChange)="onMaterialSet(blockData.material)">
              <mat-option *ngFor="let mat of materials" [value]="mat">{{mat}}</mat-option>
            </mat-select>
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Product: </mat-label>
            <mat-select required [(ngModel)]="blockData.product" name="product-field"
              id="product-field" (selectionChange)="onProductSet(blockData.product)">
              <mat-option *ngFor="let prod of products" [value]="prod">{{prod}}</mat-option>
            </mat-select>
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Block Number: </mat-label>
            <input matInput required [(ngModel)]="blockData.blockNumber" type="text" name="blockNumber-field" id="blockNumber-field">
          </mat-form-field>
        </div>
      </div>

      <div class="row">
        <div class="col-3">
          <mat-form-field>
            <mat-label>Variety: </mat-label>
            <mat-select required [(ngModel)]="blockData.variety" name="variety-field" id="variety-field"
              placeholder="Variety" (selectionChange)="onVarietySet(blockData.variety)">
              <mat-option *ngFor="let variety of varieties" [value]="variety">{{variety}}</mat-option>
            </mat-select>
          </mat-form-field>
        </div>
        <div class="col-3">
          <!-- <label for="color-field">Color: </label> -->
          <mat-form-field>
            <mat-label>Color: </mat-label>
            <mat-select required [(ngModel)]="blockData.color" name="color-field" id="color-field" placeholder="Color">
              <mat-option *ngFor="let col of colors" [value]="col">{{col}}</mat-option>
            </mat-select>
          </mat-form-field>
          <!-- <input #colField required [(ngModel)]="blockData.color" type="text" name="color-field" id="color-field" placeholder="Color"> -->
          <!-- <color-circle #colorField [colors]='["#f44336", "#e91e63", "#9c27b0", "#673ab7", "#3f51b5", "#2196f3", "#03a9f4", "#00bcd4", "#009688", "#4caf50", "#8bc34a", "#cddc39", "#ffeb3b", "#ffc107", "#ff9800", "#ff5722", "#795548", "#607d8b"]' name="color-field" id="color-field" (onChange)="blockData.color = $event.color.hex"></color-circle> -->
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Nation: </mat-label>
            <!-- <mat-select required [(ngModel)]="blockData.nation" name="nation-field"
              id="nation-field">
              <mat-option *ngFor="let nat of nations" [value]="nat">{{nat}}</mat-option>
            </mat-select> -->
            <input matInput disabled [(ngModel)]="blockData.nation" type="text" name="nation-field" id="nation-field">
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Price: </mat-label>
            <input matInput required [(ngModel)]="blockData.price" type="number" name="price-field" id="price-field">
          </mat-form-field>
        </div>
      </div>

      <div class="row">
        <div class="col-3">
          <mat-form-field>
            <mat-label>Length: </mat-label>
            <input matInput required [(ngModel)]="blockData.length" type="number" name="length-field" id="length-field">
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Width: </mat-label>
            <input matInput required [(ngModel)]="blockData.width" type="number" name="width-field" id="width-field">
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Height: </mat-label>
            <input matInput required [(ngModel)]="blockData.height" type="number" name="height-field" id="height-field">
          </mat-form-field>
        </div>
        <div class="col-3">
          <mat-form-field>
            <mat-label>Weight: </mat-label>
            <input matInput required [(ngModel)]="blockData.weight" type="number" name="weight-field" id="weight-field">
          </mat-form-field>
        </div>
      </div>

      <div class="row">
        <div class="col-3">
          <div class="file-field">
            <div class="btn btn-primary btn-sm float-left">
              <label for="image-field">Upload preview image: </label>
              <input #imageField (change)="onImageSelected($event)" name="image-field" id="image-field" type="file" accept=".png, image/png" placeholder="Upload your file">
            </div>
          </div>
        </div>
        <div class="col-3">
          <div class="file-field">
            <div class="btn btn-primary btn-sm float-left">
              <label for="zip-field">Upload models' zip: </label>
              <input #zipField (change)="zipFile = $event.target.files[0];" name="zip-field" id="zip-field" type="file" placeholder="Upload your file">
            </div>
          </div>
        </div>
      </div>
      <button type="submit" [disabled]="!blockForm.form.valid || imagePreview == null || zipFile == null || blockData.company === ''">Submit</button>
    </div>
  </form>
</div>

我希望我说得足够清楚,感谢您的帮助:)

终于找到问题的根源了。在我们的网站中,我们集成了一个 Unity3D WebGL 构建,如果我从带有 Unity 的网页移动到登录页面,Unity 进程仍然是 运行。 Unity 拥有键盘的每个输入的焦点,因此它正在捕获所有输入。

我们在更改页面时通过 解决了它。这样,输入框就可以再次接收来自键盘的输入了。

另一个解决方案,可能(我没有测试过),可能是不让 Unity 获取输入,如 this Unity forum's thread or by setting WebGLInput.captureAllKeyboardInput 中所讨论为假。