Angular 12 - Select 下拉选项基于模板中的值

Angular 12 - Select dropdown option based on the value in template

我正在做一个 POC,我在其中面临挑战。请帮我解决一下。

情况

  1. 我有需要在 select 下拉菜单中显示的类别列表
  2. 我有一个门户对象,其中包含 select 下拉列表中的类别之一

挑战: 我需要 select 在填充 select 下拉列表时匹配门户类别的选项

类别 select 下拉列表人口和 prtl 类别绑定是,

<!-- Portal Category -->
    <div class="row prtl_field_margin">
        <div class="col-4 prtl_form_field_right">
            <label for="pCategory" class="control-label prtl_form_label">Category</label>
        </div>
        <div class="col-4">
            <select class="form-control" id="pCategory" name="pCategory" [(ngModel)]="prtl.category">
                <option value="" disabled>Choose a Category</option>
                <option *ngFor="let c of categories" [ngValue]="c">{{ c.name }}</option>
            </select>
        </div>
        <div class="col-4"></div>
    </div>

组件ts文件中的prtl对象数据是,

{
  "name": "Stock Market",
  "id": 10,
  "category": {
    "id": "1",
    "name": "Cricket"
  }
}

组件ts文件中的类别数组数据是,

[
  {
    "id": "1",
    "name": "Cricket"
  },
  {
    "id": "2",
    "name": "Football"
  }
]

所需结果:类别下拉列表应包含数组中的所有类别。但是,与 prtl 对象类别匹配的类别应该是 selected。与此类似,板球类别应在填充下拉列表后 selected,但用户可以自由将其更改为足球。

首先,当您使用 ngModel 时,如果没有导入 FormsModule 到您的应用程序模块文件,请确保导入。

您可以使用以下组件来实现您的输出:

app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
 title = 'my-app';


  prtl = {
    "name": "Stock Market",
    "id": 10,
    "category": {
       "id": "2",
       "name": "Football"
    }
  };

  categories = [
    {
     "id": "1",
     "name": "Cricket"
    },
    {
     "id": "2",
     "name": "Football"
    }
  ];
  categoryToSelect = this.prtl.category;
}

app.component.html

<div class="row prtl_field_margin">
<div class="col-4 prtl_form_field_right">
    <label for="pCategory" class="control-label prtl_form_label">Category</label>
</div>
<div class="col-4">
    <select class="form-control" id="pCategory" name="pCategory" [(ngModel)]="categoryToSelect.id">
        <option value="" disabled>Choose a Category</option>
        <option *ngFor="let c of categories" [ngValue]="c.id">{{ c.name }}</option>
    </select>
</div>
<div class="col-4"></div>

在上面的代码中,我将您的 selection Football 设置为默认值。此外,当为 select 下拉菜单提供 ngValue 时,请提供唯一值作为标识符,而不是整个对象本身。

以前的解决方案不起作用(至少,在我的测试中不起作用)。

我试过了,你可以测试它在 here

中是否有效

摘录:

import { Component, OnInit } from "@angular/core";

interface CategoryInterface {
  id: string;
  name: string;
}

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent implements OnInit {
  title = "Juan Berzosa select of an object value of a HTML select component solution";

  prtl = {
    name: "Stock Market",
    id: 10,
    category: {
      id: "2",
      name: "Football"
    }
  };

  categories: CategoryInterface[];

  selectedCategory: CategoryInterface;

  constructor() {
    this.categories = [
      {
        id: "1",
        name: "Cricket"
      },
      {
        id: "2",
        name: "Football"
      }
    ];

    const selectedCategoryArray = this.categories.filter(
      (itemCategory) =>
        this.prtl.category.id === itemCategory.id &&
        this.prtl.category.name === itemCategory.name
    );

    this.selectedCategory = selectedCategoryArray[0];
  }
}

HTML:

<div>
  <h1>
    Welcome to {{ title }}!
  </h1>
</div>
<!-- Portal Category -->
<div class="row prtl_field_margin">
  <div class="col-4 prtl_form_field_right">
    <label for="pCategory" class="control-label prtl_form_label"
      >Category</label
    >
  </div>
  <div class="col-4">
    <select
      class="form-control"
      id="pCategory"
      name="pCategory"
      [(ngModel)]="selectedCategory"
    >
      <option value="" disabled>Choose a Category</option>
      <option *ngFor="let c of categories" [ngValue]="c">{{ c.name }}</option>
    </select>
  </div>
  <div class="col-4"></div>
</div>

P.S:正如@a​​run-s 所说,不要忘记在 app.module.ts:

中添加 FormsModule
...
import { FormsModule } from "@angular/forms";
...
@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule,
  FormsModule],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

使用唯一标识符作为下拉选项的值,在您的例子中是类别 ID。现在将类别 ID 从门户对象传递到 ngModel 指令以将值绑定到下拉列表。您可以使用 ngModelChange 指令来侦听类别 ID 值更改并在门户对象中更新相同的值。您可以在下面找到示例。

示例: component.html

<select
  id="category"
  [ngModel]="prtlObj.category.id"
  (ngModelChange)="updateObj($event)"
>
  <option
    *ngFor="let item of categories"
    [value]="item.id"
  >{{ item.name }}</option>
</select>

component.ts

updateObj(id: string) {
  const category = this.categories.find(x => x.id === Number.parseInt(id));
  this.prtlObj = {
    ...this.prtlObj,
    category
  };
}

可以找到完整的工作示例 here