是否可以使用动态复选框在Angular 7中过滤表中的数据?

时间:2019-04-25 14:30:25

标签: javascript html angular angular7

我正在尝试使用动态复选框过滤表中的数据。目的是使用户可以选择和取消选择多个复选框以过滤数据。

我认为它“起作用了”。我的问题是,我不知道如何判断该复选框是选中还是未选中。另外,当选中多个复选框时,我遇到了问题。

我应该将$ event传递给checkBox函数/其他吗?

/////from service.ts
    private commList: IComm[] = [];
    private productNames: string[] = [];
    private levelsList: string[] = [];

    constructor(private apiService: ApiService) {
      this.apiService.get('/product').subscribe(
        result => {
          console.log(result);
          this.commList = result;
          this.productNames = result.map(p => p.MarketName)
          .filter((c, index, array) => array.indexOf(c) == index).sort();
          this.levelsList = result.map(p => p.Level)
          .filter((c, index, array) => array.indexOf(c) == index).sort();

          console.log(this.productNames);
          console.log(this.levelsList);
        }
      );
    }


    getCommList(filter: string = null): IComm[] {
      return this.commList
            .filter(p => filter == null || filter == p.MarketName);
    }





/////from component.ts

  comList: IComm[] = [];
  public selectedFilter = null;
  public productsPerPage = 10;
  public selectedPage = 1;

  constructor(private commService: CommService) {}


  get commList(): IComm[] {
    const pageIndex = (this.selectedPage - 1) * this.productsPerPage;
    return this.commService.getCommList(this.selectedFilter).slice(pageIndex, pageIndex + this.productsPerPage);
  }


// this is where I'm having trouble.... 
// it's passing the value of the check box, but not sure how to tell if it's 
// checked or un-checked... 
// also, should I have an filter array / other that it can add / minus from?
  changeCheckbox(pFilter, i) {
    if (pFilter) {

      console.log(pFilter);
      this.selectedFilter = pFilter;
    }
  }

  levelCheckbox(levelFilter, i) {
    if (levelFilter) {

      console.log(levelFilter);
      this.selectedFilter = levelFilter;
    }
  }

  changePage(newPage: number) {
    this.selectedPage = newPage;
  }

  changePageSize(newSize: number) {
    this.productsPerPage = Number(newSize);
    this.changePage(1);
  }

  get pageCount(): number {
    return Math.ceil(this.commissionsService.getCommissionsList(this.selectedFilter).length / this.productsPerPage);
  }
 <!-- dynamic ck boxes for filters 1 .. -->

<div class="form-check" *ngFor="let pFilter of productNames; let i = index;">
            <label class="form-check-label" for="pFilter{{pFilter.value}}">
              <input class="form-check-input" type="checkbox" id="pFilter{{pFilter.value}}" name="pFilterOptions"
                (change)="changeCheckbox(pFilter, i)" [checked]="pFilter.checked">
              {{pFilter}}
            </label>
          </div>

 <!-- dynamic ck boxes for filters 2 .. -->
<div class="form-check" *ngFor="let levelFilter of levelsList; let i = index;">
            <label class="form-check-label" for="levelFilter{{levelFilter.value}}">
              <input class="form-check-input" type="checkbox" id="levelFilter{{levelFilter.value}}" name="levelFilterOptions"
                (change)="levelCheckbox(levelFilter, i)" [checked]="levelFilter.checked">
              {{levelFilter}}
            </label>
          </div>

          
 <!-- table of data .. -->
 
 <table class="table table-striped table-sm">
          <thead>
            <tr>
              <th>Product</th>
              <th>My Age</th>
              <th>Year 1</th>
              <th>Year 2 - 3</th>
              <th>Years 2 - 5</th>

            </tr>
          </thead>
          <tbody>
            <tr *ngFor="let comm of commList">
              <td>
                {{comm.Name}}
                <br />
                {{comm.Code}}
              </td>
              <td>
                <div>
                  Age {{comm.MyStart}} - {{comm.MyEnd}}
                </div>
              </td>
              <td>

                <div *ngIf="comm.Year === 1">
                  {{comm.MyVal}}.00%
                </div>

              </td>
              <td>

                <div *ngIf="comm.Year > 2">
                  {{comm.MyVal}}.00%
                </div>

              </td>
              <td>
                <div *ngIf="comm.Year > 3">
                  {{comm.MyVal}}.00%
                </div>
              </td>
            </tr>
          </tbody>
        </table>

1 个答案:

答案 0 :(得分:0)

在我看来,简化实现的一种方法是使用带有数组组的表单,然后订阅该组上的更改。发生更改时,您会将过滤器应用于列表。

TS

import { OnDestroy, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, FormArray } from '@angular/forms';
import { Subscription } from 'rxjs';

export class MyComponent implements OnInit, OnDestroy {

    myFilters: MyFilter[];
    myForm: FormGroup;

    private filterSubscription: Subscription;

    constructor(private fb: FormBuilder) { }

    ngOnInit() {
        // this.myfilters = ...... initialize your filters ......
        this.myForm = this.fb.group({
            filters: this.fb.array(this.getFiltersControls())
        });

        this.filterSubscription = this.myForm.get('filters').valueChanges.subscribe(values => {
            const selectedFilters: MyFilter[] = values.filter(v => v.checked).map(v => v.myFilter);
            // do the query using the checked filters
            this.refreshList(selectedFilters);
        });
    }

    ngOnDestroy() {
        if (this.filterSubscription) {
            this.filterSubscription.unsubscribe();
        }
    }

    // initialize your filter controls
    private getFiltersControls(): FormGroup[] {
        return this.myFilters.map(filter => {
            return this.fb.group({
                checked: this.isFilterCheckedByDefault(filter),
                myFilter: filter
            });
        });
    }

    private isFilterCheckedByDefault(filter: MyFilter): boolean {
        // apply logic to calculate default value base on filter name or whatever
        switch (filter.name) {
            case 'age':
                return true;
            case 'name':
                return false;
            default:
                return false;
        }
    }

    private refreshList(selectedFilters: MyFilter[]): void {
        // this.commList = this.commissionsService.getCommissionsList.....
    }
}

class MyFilter {
    name: string;
    // whatever other props are needed
}

HTML

<!-- dynamic ck boxes for all filters .... -->
<div [formGroup]="myForm">
  <div formArrayName="filters" *ngFor="let ctrl of myForm.get('filters').controls; let i = index;">
    <div [formGroupName]="i">
      <label [for]="'levelFilter' + ctrl.value.myFilter.name"></label>
      <input [id]="'levelFilter' + ctrl.value.myFilter.name" type="checkbox" formControlName="checked" />
    </div>
  </div>
</div>

<!-- table of data .... -->