【问题标题】:Need help to get correct values from checkboxes & dropdown select, to display correct data需要帮助从复选框和下拉选择中获取正确的值,以显示正确的数据
【发布时间】:2019-09-18 03:11:39
【问题描述】:

我无法从 Mat-Select 和 Mat-Checkbox 获取要显示的正确数据。 我想要做的是从已选择的用户那里获取值。从所选值执行 if-else 语句以检查是否满足条件,如果满足则显示正确的数据视图。当用户更新他们的选择时,还希望动态更改为正确的数据视图。 我在 Stackblitz 上运行了示例应用程序:https://stackblitz.com/github/tatemcg/angular-mat-sample 感谢您的帮助。

HTML。

<div>
    <form>
        <mat-form-field id="dropdown1">
            <mat-label><h4>Continent</h4></mat-label>
            <br />
            <br />
            <mat-select [(ngModel)]="selectedSource" name="food" (selectionChange)="changeSources($event.value)">
                <mat-option *ngFor="let source of dataSources" [value]="source.id">
                    {{source.sourceName}}
                </mat-option>
            </mat-select>
        </mat-form-field>
        <mat-form-field id="dropdown2">
            <mat-label><h4>Country</h4></mat-label>
            <br />
            <br />
            <mat-select [(ngModel)]="selectedType" name="foods" (selectionChange)="changeCountryType($event.value)">
                <mat-option *ngFor="let countryType of countryTypes" [value]="countryType.id">
                    {{countryType.countryType}}
                </mat-option>
            </mat-select>
        </mat-form-field>
    </form>
</div>

<div>
    <mat-drawer-container class="example-container">
        <mat-drawer class="insideDiv" #sideNav mode="side" opened="true" [position]="nav_position">
            Population Year
            <ul style="list-style-type:none;">
                <li>
                    <mat-checkbox id="year2000" [(ngModel)]="twoThousandChecked" (change)="onYearCheckboxChange($event, '2000')"> 2000 </mat-checkbox>
                </li>
                <li>
                    <mat-checkbox [(ngModel)]="twoThousand10Checked" (change)="onYearCheckboxChange($event, '2010')"> 2010</mat-checkbox>
                </li>
            </ul>
            Gender
            <ul style="list-style-type:none;">
                <li>
                    <mat-checkbox id="femaleCheckBox" [(ngModel)]="femaleChecked" (change)="onGenderCheckboxChange($event, 'female')"> Female </mat-checkbox>
                </li>
                <li>
                    <mat-checkbox [(ngModel)]="maleChecked" (change)="onGenderCheckboxChange($event, 'male')"> Male</mat-checkbox>
                </li>
            </ul>
        </mat-drawer>
        <mat-drawer-content>
            <button class="expandCollapseBTN" (click)="sideNav.toggle()" mat-button> Expand/Collapse </button>
            <div #dataViewNode id="dataNode">
                <br />
                <br />
                <br />
                <br />
                <br />
                <h3>Here is your data for {{selectedType}} and {{yearNum}} and {{genderChoice}}</h3>
            </div>
        </mat-drawer-content>
    </mat-drawer-container>
</div>

TS

export class DataViewComponent implements OnInit, OnChanges {



  public selectedSource: string;
  public selectedType: string;


  dataSources = [
    { id: 'id1', sourceName: 'North America' }
  ];
  countryTypes = [
    { id: 'id1', countryType: 'Canada' },
    { id: 'id2', countryType: 'Mexico' },
    { id: 'id3', countryType: 'United States' }
  ];

  constructor() { }

  changeSources(data) {
    alert("Continent " + data);
    console.log("Continent " + this.selectedSource);
    this.showSelectedDataView(this.selectedSource, this.selectedType, this.yearNum);
  }
  changeCountryType(data) {
    alert("Country Selected" + data);
    console.log("Country Selected " + this.selectedType);
    this.showSelectedDataView(this.selectedSource, this.selectedType, this.yearNum);
  }

  public yearNum = []; twoThousandChecked; twoThousand7Checked;
  public genderChoice = []; femaleChecked; maleChecked;

  onYearCheckboxChange(event, value) {
    if (event.checked) {
      this.yearNum.push(value);
      this.yearNum = [...this.yearNum];
      alert("Year " + this.yearNum);
    }
    if (!event.checked) {
      let index = this.yearNum.indexOf(value);
      if (index > -1) {
        this.yearNum.splice(index, 1);
        this.yearNum = [...this.yearNum];
      }
    }
    this.showSelectedDataView(this.selectedSource, this.selectedType, this.yearNum);
    console.log("Year List " + this.yearNum);
  }
  onGenderCheckboxChange(event, value) {
    if (event.checked) {
      this.genderChoice.push(value);
      this.genderChoice = [...this.genderChoice];
      alert("Gender " + this.genderChoice);
    }
    if (!event.checked) {
      let index = this.genderChoice.indexOf(value);
      if (index > -1) {
        this.genderChoice.splice(index, 1);
      }
    }
    this.showSelectedDataView(this.selectedSource, this.selectedType, this.yearNum);
    console.log("Gender List: " + this.genderChoice);
  }
  ngOnInit() {
  }
  ngOnChanges() {
    this.showSelectedDataView(this.selectedSource, this.selectedType, this.yearNum);
  }
  showSelectedDataView(selectedSource: string, selectedType: string, yearNum: any) {
    if (this.selectedSource === 'id1' && this.selectedType === 'id1') {
      alert("You Selected Data For " + this.selectedSource + " " + this.selectedType)
      console.log(" North America and Canada");
    }
    else if (this.selectedSource === 'id1' && this.selectedType === 'id2') {
      alert("You Selected Data For " + this.selectedSource + " " + this.selectedType)
      console.log(" North America and Mexico");
    }
    else if (this.selectedSource === 'id1' && this.selectedType === 'id3') {
      alert("You Selected Data For " + this.selectedSource + " " + this.selectedType)
      console.log(" North America and United States");
    }
    else if (this.selectedSource === 'id1' && this.selectedType === 'id1') {
      for(var i = 0; i < yearNum.length(); i++)
      {
        if(yearNum[i] === '2000')
        {
          alert("You Selected Data For " + this.selectedSource + " " + this.selectedType + " and Year " + this.yearNum)
          console.log(" North America and Canada and 2000 ");
        }
      }

    }
    else if (this.selectedSource === 'id1' && this.selectedType === 'id1' && this.yearNum === this.twoThousandChecked && this.genderChoice === this.maleChecked) {
      alert("You Selected Data For " + this.selectedSource + " " + this.selectedType + " and Year " + this.yearNum + " and for " + this.genderChoice)
      console.log(" North America and Canada and 2000 and Male");
    }
  }
}

【问题讨论】:

    标签: javascript html angular angular-material


    【解决方案1】:

    你代码的问题在于下面的代码

    ngOnChanges() { this.showSelectedDataView(); }

    当用户选择任何复选框时,这永远不会触发。而这背后的原因是

    ngOnChanges 仅在输入更改来自模板时运行 像绑定一样。如果手动设置 像这个component.someInput = aValue,发生在外面 更改检测周期,您需要以某种方式让 Angular 知道 你改变了一些东西。

    作为official docs 引用

    一个生命周期钩子,当一个对象的任何数据绑定属性被调用时 指令的变化。定义一个 ngOnChanges() 方法来处理 变化。

    所以为了解决问题,你可以做的是。

    1.使用以下手动触发更改检测

    constructor(private cd: ChangeDetectorRef) { }
    

    然后使用

    this.cd.detectChanges();
    

    当你想用角度来检测变化时。

    2。需要时给你打电话showSelectedDataView
    每当您看到有变化并且应该更新数据视图时调用代码中所需的函数。

    当您使用数组和对象时,如果您使用.push 或更改不会触发更改检测的键的值。在这种情况下,您可以使用下面来触发更改检测。

    this.yearNum = [...this.yearNum];
    

    如果对象

    const obj = {val: '123'}
    obj.val = '345';
    obj = {...obj}
    

    更新stackblitz demo试试看。

    希望这会有所帮助:)

    【讨论】:

    • Manish,感谢您的回复。我做了一些更新,并在下拉列表更改函数中调用 showSelectedDataView() 及其参数。它按预期工作。但是对于复选框,我真的不知道如何让它工作或使用复选框更改函数中传递的正确参数调用 showSelectedDataView()。还编辑了我的 stackblitz。
    • OK 因此,每当您像 this.yearNum = [...this.yearNum]; 那样从中添加或删除项目时,您都必须将数组重新分配给自身,并在复选框的更改事件处理程序上调用此函数 this.showSelectedDataView(this.selectedSource, this.selectedType);正如我在回答中提到的那样。这是您的 stackblitz 演示的编辑版本stackblitz.com/edit/github-mjztj6 早期的更改并未反映为私有 stackblitz
    • 我还必须在 showSelectedDataView() 中添加另一个参数,对吗?这行得通吗? showSelectedDataView(selectedSource:字符串,selectedType:字符串,yearNum:[])?另外我认为我需要在 else if 语句内有一个循环来处理数组,以确定数组中的内容并对其做出响应,对吗?谢谢!
    • 这完全取决于您希望如何利用数据和选择。所以是的,您可能必须为您的情况这样做。
    • 我只想让我最后的 2 个 else if 语句运行并获得预期的 console.log()。所以我有。 showSelectedDataView(selectedSource: string, selectedType: string, yearNum : any ) 然后在 ngOnChanges() 或 onYearCheckboxChange() 中使用 this.showSelectedDataView(this.selectedSource, this.selectedType, this.yearNum) 调用它。我仍然没有在带有 for 循环的 else if 语句中得到预期的结果,它位于 showSelectedDataView() 内部。我更新了上面的代码和stackblitz。不知道如何解决这个问题,感谢任何指针。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-03
    • 2019-04-04
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多