【问题标题】:How to implement a dependant <select> inside HTML table如何在 HTML 表中实现依赖 <select>
【发布时间】:2020-10-10 10:19:28
【问题描述】:

我已经实现了如下表。两列是可编辑的,我们可以从下拉列表中选择值。我使用 HTML 选择实现了这一点。 “Category tier 2”中的值取决于我在“Category tier 1”列中选择的值。

当我在特定行的“Category tier 1”列中选择一个值时,“Category tier 2”列中的所有行值都会更改,但我只想更改“Category tier 2”的值那个特定的行。

stackblitz link.

【问题讨论】:

    标签: angular typescript html-table


    【解决方案1】:

    您可以将表中的每一行创建为组件,例如 my-row.component,并将其用作 tr 上的属性。在这些变化之后

    app.component.html

    <div>
      <table style="width:100%">
            <th *ngFor = "let column of headers">
                {{column}}
            </th>
            <th>
                Category tier 1
            </th>
            <th>
                Category tier 2
            </th>
            <ng-container *ngFor = "let row of rows">
            <tr [headers]="headers" [row]="row" [categories]="categories" [category_tier1]="category_tier1" app-my-row></tr>   
            </ng-container>
        </table>
    </div>
    

    app.component.ts

    import { Component, VERSION } from '@angular/core';
    interface Category{
        category_id: number;
        tier1: string;
        tier2: string;
    }
    @Component({
      selector: 'my-app',
      templateUrl: './app.component.html',
      styleUrls: [ './app.component.css' ]
    })
    export class AppComponent  {
      categories:Category[]=[
        {
        "category_id": 2,
        "tier1": "ABC",
        "tier2": "A"
        },
        {
        "category_id": 3,
        "tier1": "ABC",
        "tier2": "B"
        },
        {
        "category_id": 4,
        "tier1": "ABC",
        "tier2": "C"
        },
        {
        "category_id": 5,
        "tier1": "DE",
        "tier2": "D"
        },
        {
        "category_id": 6,
        "tier1": "DE",
        "tier2": "E"
        },
        {
        "category_id": 7,
        "tier1": "FG",
        "tier2": "F"
        },
        {
        "category_id": 8,
        "tier1": "FG",
        "tier2": "G"
        }
        ];
          category_tier1:string[]=[];
          category_tier2:string[]=[];
    
          headers=["Firstname","Lastname","Age"];
    
          rows=[
            {
              "Firstname":"Jill",
              "Lastname":"Smith",
              "Age":"50"
            },
            {
              "Firstname":"Eve",
              "Lastname":"Jackson",
              "Age":"94"
            },
            {
              "Firstname":"John",
              "Lastname":"Doe",
              "Age":"80"
            }
      ];
    
      constructor(){
        for(let i in this.categories){
                    this.category_tier1.push(this.categories[i].tier1);
                  }
                  this.category_tier1=Array.from(new Set(this.category_tier1));
      }
    
    }
    

    app.component.css

    table, th {
        border: 1px solid black;
        border-collapse: collapse;
        table-layout: fixed; width: 100%
      }
      th {
        padding: 15px;
        overflow: hidden;
      }
    

    my-row.component.html

    <td *ngFor="let column of headers">
        {{row[column]}}
    </td>
    <td>
        <select (change)="selectTier1($event)">
                      <option *ngFor="let c of category_tier1" [value]="c">{{c}}</option>
                    </select>
    </td>
    <td>
        <select (change)="selectTier2($event)">
                    <option *ngFor="let c of category_tier2" [value]="c">{{c}}</option>
                  </select>
    </td>
    

    my-row.component.ts

    import { Component, OnInit, Input } from '@angular/core';
    
    @Component({
      selector: '[app-my-row]',
      templateUrl: './my-row.component.html',
      styleUrls: ['./my-row.component.css']
    })
    export class MyRowComponent implements OnInit {
      @Input() public headers;
      @Input() public row;
      @Input() public categories;
      @Input() public category_tier1;
      public category_tier2;
      constructor() { }
    
      ngOnInit() {
      }
      selectTier1(event){
        this.category_tier2=[];
        for(let c in this.categories){
          if(this.categories[c].tier1===event.target.value){
            this.category_tier2.push(this.categories[c].tier2);
          }
        }
      }
      selectTier2(event){
    
      }
    }
    

    my-row.component.css

     td {
        padding: 5px;
        overflow: hidden;
      }
    
    select {
        border: 0;
        height: 60%;
        width: 100%;
    }
    
    td {
        border: 1px solid black;
        border-collapse: collapse;
        table-layout: fixed; width: 100%
      }
    

    通过使用上述方法,每一行都将获得各自的第 2 层数组。

    工作 Stackblitz :- https://stackblitz.com/edit/angular-ivy-dcjc1y

    【讨论】:

      【解决方案2】:

      更改代码中的 3 个位置:

      • 将第 2 层类别定义为数组而不是字符串:

          categories_tier2:string[][] = []; // replace category_tier2:string[] = []
        
      • 在 HTML 中,修改代码以呈现 tier2 select,并将行索引传递给 tier1 select 事件处理程序:

        <tr *ngFor = "let row of rows; index as i">  // Use row index here
            <td  *ngFor = "let column of headers">
              {{row[column]}}
            </td>
            <td>
                <select (change)="selectTier1($event,i)"> // Pass row index to handler
                  <option *ngFor="let c of category_tier1" [value]="c">{{c}}</option>
                </select>
            </td>
            <td>
              <select (change)="selectTier2($event)">  // Adjust to changed array
                <option *ngFor="let c of categories_tier2[i]" [value]="c">{{c}}</option>
              </select>
            </td>
          </tr> 
        

      然后在 tier1 选择处理程序中,使用行索引来呈现正确的 tier2 列表:

          selectTier1(event, i){
              this.categories_tier2[i]=[];
              for (let c of this.categories){
                 if (c.tier1===event.target.value) {
                   this.categories_tier2[i].push(c.tier2);
                 }
              }
           }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-03-02
        • 1970-01-01
        • 1970-01-01
        • 2019-10-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多