【问题标题】:get value of all the drop down on change event of one drop down在一个下拉列表的更改事件中获取所有下拉列表的值
【发布时间】:2021-05-18 18:45:52
【问题描述】:

我是 Angular 世界的新手,我的 html 页面上有一个情况,我有 5 个下拉菜单,我想在任何下拉菜单的点击事件中读取所有 5 个下拉菜单的值,以便我可以对所有选定的值应用过滤器以在数据网格中显示数据。

所以我的问题是,Angular 是否可以做到这一点,如果可以,请分享一些例子。

app.component.html

    <div>  
      <table>      
        <tbody>
        <tr> 
          <td> Compnay Name :  
            <select #cmpDropDown (change) = "getChangeCompnyDetails(cmpDropDown.value, deptDropDown, prodDropDown)">
              <option [value]="cmpItem.cmpId" *ngFor = "let cmpItem of cmpResp;">{{cmpItem.cmpName}}</option>
            </select>
          </td>
          <td> </td>         
          <td> Department Name  
            <select #deptDropDown (change) = "getChangeDeptDetails(deptDropDown.value, cmpDropDown, prodDropDown)">
              <option [value]="deptItem.deptId" *ngFor = "let deptItem of deptResp;">{{deptItem.deptName}}</option>
            </select>
          </td>
          <td> </td>         
          <td> Product Name              
            <select #prodDropDown (change) = "getChangeProdDetails(prodDropDown.value, cmpDropDown, deptDropDown)">
              <option [value]="prodItem.prodId" *ngFor = "let prodItem of prodResp;" >{{prodItem.prodName}}</option>              
            </select>
          </td>
        </tr>   
      </tbody>  
      </table> 
    </div>

    <div> </div>
    <!-- Show data in grid -->    
    <div>
      <table style="width:100%" border="1">  
        <thead >
          <tr> </tr> <tr> </tr>
          <tr >            
            <th scope="col">Order No</th>
            <th scope="col">ProductName</th>
            <th scope="col">Status</th>                      
          </tr>
        </thead>
        <tbody>
          <tr *ngFor = "let dataRowItem of deliveryDataResp">                       
            <td> {{dataRowItem.ordNum}}</td>
            <td> {{dataRowItem.prodName}}</td>
            <td> {{dataRowItem.status}}</td>            
          </tr>
        </tbody>
      </table>
    </div>    
  </div>

app.component.ts :-

import { Component, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})

export class AppComponent implements OnInit{
    title = 'AngularUi';  
    
    public deliveryDataResp    : any;
    public deliveryDataRespBck : any;
    public deptResp            : any = [ {"deptId": "ALL", "cmpId": "ALL", "deptName": "ALL"}];
    public prodResp            : any = [ {"prodId": "ALL", "deptId": "ALL", "prodName": "ALL"}];
        
    ngOnInit(){     

        //Get Compnay List
        let obj = this.http.get(cmpApiUrl).subscribe((cmpResp)=>{
            this.cmpResp = cmpResp;        
        })
    
        //Get delivery details 
        let deliveredObj = this.http.get(deliveredApiUrl).subscribe((deliveryDataResp)=>{
            this.deliveryDataResp = deliveryDataResp;
            this.deliveryDataRespBck = deliveryDataResp;
        })
                
    }//End of ngOnInIt

    getChangeCompnyDetails(cmpDropDownVal: String, deptDropDown: HTMLSelectElement, prodDropDown: HTMLSelectElement): void {
        
        calling department api with cmpDropDownVal, now API will give list of department associated with Company (with this call department drop down will be updated with new list of department values) 

        //As department drop down is updated with above call so now we need updated department list (how we will get updated department dropdown value ?)
        this.departmentIdSelected = this.deptResp[0].deptId;  //here I am trying to get the data from object returned by subscribe but as subscribe is async call so deptId is not accessible here hence finding way to get selceted value of department drop down so that can filter on that id
        
        this.prodIdSelected = this.prodResp[0].prodId; 
        
        this.filterDataGrid(cmpIdSelected, departmentIdSelected, prodIdSelected)
    }
    
    getChangeDeptDetails($event){
        this.deptIdSelected = event.target.value;
        
        //get product list by calling product api for deptId
    }
    
    filterDataGrid()
    {
        this.deliveryDataResp = this.deliveryDataRespBck.filter( (obj: any) => {             
            if(obj.cmpId === cmpSelVal && obj.deptId === deptSelVal && obj.prodId === prodSelVal){return true;} return false;
        })
    }
}

【问题讨论】:

  • 如果您在初次尝试时提供一些代码,将会很有帮助。一些 HTML &Typescript。
  • 您是否尝试过为每个下拉菜单使用[(ngModel)]

标签: angular angular11


【解决方案1】:

您需要 [(ngModel)] 意味着您的所有下拉菜单的两种方式数据绑定,因此一旦您点击,您就可以借助我们绑定的变量在该点击方法中获取所有下拉菜单的选定值到所有下拉菜单。

请查看以下示例,了解我们如何使用 [(ngModel)] 进行下拉并获取所选值。

<select [(ngModel)]="selectedValue">
  <option *ngFor="let item of Products" [value]="item">{{item.productName}}</option>
</select>

您需要在 ts 文件中将 selectedValue 声明为变量,以便您在该变量中获得下拉选择值。

希望它能帮助您解决问题。

提前致谢!

【讨论】:

    【解决方案2】:

    您好,您可以按照以下示例进行操作,我在 slackblitz 中创建了一个。

    https://stackblitz.com/edit/angular-ivy-bmof5o?file=src%2Fapp%2Fapp.component.ts

    【讨论】:

    • 感谢 Nirmalya 的回复。在更改事件中,我还调用 API 来更改让我们说第二个下拉列表的值,那么我将如何在第一个下拉更改事件中执行 API 调用,以及我将如何获得第二个下拉列表的更新值和其余下拉列表值。
    【解决方案3】:

    无需手动完成所有操作。 你可以有角度的反应形式, 在您的应用模块.ts 中

    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { ReactiveFormsModule } from '@angular/forms';
    
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    
    @NgModule({
      declarations: [
        AppComponent
      ],
      imports: [
        BrowserModule,
        AppRoutingModule,
        ReactiveFormsModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    在你的 component.ts 中

    import { Component } from '@angular/core';
    import { FormBuilder, FormGroup, Validators } from '@angular/forms';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.scss']
    })
    export class AppComponent {
    
      myForm: FormGroup;
    
      constructor(private fb: FormBuilder) {}
    
      ngOnInit() {
        this.myForm = this.fb.group({
          companyName: ['1'],
          departmentName: ['1'],
          productName: ['1']
        })
    
        this.myForm.valueChanges.subscribe(x => {
          this.filterData(x)
        });
      }
    
      filterData(data) {
        console.log(data)
        // apply filters here
      }
    }
    

    在你的component.html中

    <form [formGroup]="myForm">
    
      <label>Company Name</label>
      <select formControlName="companyName">
        <option value="1">company 01</option>
        <option value="2">company 01</option>
      </select>
    
      <label>Department Name</label>
      <select formControlName="departmentName">
        <option value="1">department 01</option>
        <option value="2">department 02</option>
      </select>
    
      <label>Product Name</label>
      <select formControlName="productName">
        <option value="1">product 01</option>
        <option value="2">product 02</option>
      </select>
    
    </form>
    

    这是一个例子,你可以根据这个更新你的文件或参考下面的链接

    https://fireship.io/lessons/basics-reactive-forms-in-angular/

    【讨论】:

      【解决方案4】:

      您可以使用 Angular [模板参考变量][1] 获取所有下拉列表的值。

      让我们考虑一个最基本的例子,一个带有 5 个选择标签(下拉菜单)的 HTML:

      <div>
        <select #select1 (change)="onChangeEventOne(select1, select2, select3, select, select5)">
          <option>Dropdown 1 - Option 1</option>
          <option>Dropdown 1 - Option 2</option>
          <option>Dropdown 1 - Option 3</option>
          <option>Dropdown 1 - Option 4</option>
          <option>Dropdown 1 - Option 5</option>
        </select>
      </div>
      
      <div>
        <select #select2 (change)="onChangeEventTwo(select1, select2, select3, select, select5)">
          <option>Dropdown 2 - Option 1</option>
          <option>Dropdown 2 - Option 2</option>
          <option>Dropdown 2 - Option 3</option>
          <option>Dropdown 2 - Option 4</option>
          <option>Dropdown 2 - Option 5</option>
        </select>
      </div>
      
      <div>
        <select #select3 (change)="onChangeEventThree(select1, select2, select3, select, select5)">
          <option>Dropdown 3 - Option 1</option>
          <option>Dropdown 3 - Option 2</option>
          <option>Dropdown 3 - Option 3</option>
          <option>Dropdown 3 - Option 4</option>
          <option>Dropdown 3 - Option 5</option>
        </select>
      </div>
      
      <div>
        <select #select4 (change)="onChangeEventFour(select1, select2, select3, select, select5)">
          <option>Dropdown 4 - Option 1</option>
          <option>Dropdown 4 - Option 2</option>
          <option>Dropdown 4 - Option 3</option>
          <option>Dropdown 4 - Option 4</option>
          <option>Dropdown 4 - Option 5</option>
        </select>
      </div>
      
      <div>
        <select #select5 (change)="onChangeEventFive(select1, select2, select3, select, select5)">
          <option>Dropdown 5 - Option 1</option>
          <option>Dropdown 5 - Option 2</option>
          <option>Dropdown 5 - Option 3</option>
          <option>Dropdown 5 - Option 4</option>
          <option>Dropdown 5 - Option 5</option>
        </select>
      </div>
      

      注意每个选择中的行:

      #select1 (change)="onChangeEventOne(select1, select2, select3, select4, select5)"
      #select2 (change)="onChangeEventTwo(select1, select2, select3, select4, select5)"
      ...
      #select5 (change)="onChangeEventFive(select1, select2, select3, select, select5)"
      

      在这种情况下,我用模板变量标记每个选择。这为我提供了一个可以在所有 HTML 代码中使用的参考。 模板引用在其开头由# 标识。

      接下来,我使用(change) 事件来捕捉任何下拉菜单中发生更改的时间。 然后我将每个下拉列表的值传递给它自己的函数。每个函数都接收自己的值并引用每个选择器,以便我可以更改它们:

      onChangeEventOne(select1: HTMLSelectElement, select2: HTMLSelectElement, select3: HTMLSelectElement, select4: HTMLSelectElement, select5: HTMLSelectElement): void {
        if (select1.value.startsWith('a') {
          select2.value = "";
          select3.value = "";
          select4.value = "";
          select5.value = "";
        } else {
          select1.value = "";
        }
      }
      

      在上面的示例中,当第一个下拉列表发生变化时,我将其值作为第一个参数传递,并将对其他下拉列表的引用作为接下来的四个参数传递。 这允许我以更直接的方式为每个下拉菜单设置一个新值。

      如果你愿意 [1]:https://angular.io/guide/template-reference-variables

      【讨论】:

      • :- 感谢您的及时回复。我需要在 (onChangeEvent()) 上使用相同的功能吗?因为在更改第一个下拉菜单时,我必须更新第二个下拉菜单的值,以便我可以在同一个函数中执行此操作?
      • @SwapnilM 我已更新答案以反映您的要求。
      • 非常感谢您的努力,但实际上在第一次下拉更改事件中,我能够获取其余下拉列表的值,但我正在调用 API 以从第一次下拉更改中更新第二个下拉列表的值事件所以现在第二个下拉列表的值发生了变化,有没有办法从第一个下拉更改事件中获取更新的值?
      • 我已经更新了我的答案,以更好地匹配我认为你想要做的事情,但我不确定它是否是这个。据我了解,您想捕获所有下拉列表,检查第一个并更新其他下拉列表的值,在这种情况下您没有修改可见选项。对吗?
      • 你一开始是正确的,所以我有两个要求 1. 获取下拉列表当前选定值的值(我能够用你的第一个解决方案来使用模板参考变量)现在在与 第二个下拉列表的值因 API 调用而更改的相同更改事件中的第二个要求,所以我需要更新的值 请注意:- 我已经用你的方法更新了我的示例。因此,您可以参考更新后的问题并查看来自 getChangeCompnyDetails() 的调用
      【解决方案5】:

      我能够使用 ng-model 解决这个问题,并且能够访问 .ts 中的值。

      【讨论】:

        猜你喜欢
        • 2021-06-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-11-05
        • 1970-01-01
        • 1970-01-01
        • 2022-09-28
        • 1970-01-01
        相关资源
        最近更新 更多