需要帮助以从复选框和下拉菜单中获取正确的值,以显示正确的数据

时间:2019-09-18 03:11:39

标签: javascript html angular angular-material

我无法从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");
    }
  }
}

1 个答案:

答案 0 :(得分:0)

您的代码中的问题在于下面的代码

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进行尝试。

希望这会有所帮助:)