按2个条件对数组中的角项进行过滤

时间:2019-02-19 20:15:55

标签: angular typescript filter

我创建了排序工具条,可以根据类别和价格过滤产品列表。按类别过滤可以正常工作。 sidebar 我在根据产品价格进行过滤时遇到问题。如果我将类别设置为“ Smartfons”,并且对价格高于2000的产品进行过滤,则在我的情况下,它将正确返回Iphone X:Price more than 2000 但是,当我将过滤条件更改为“全部”时,我有这部手机,它应该返回3部手机:All smartfons

    export class ProductComponent implements OnInit {
  filteredProduct: Products[] = [];
  products: Products[] = [];
  currentSorting: string;
  wrapper = true;
  @ViewChild('filtersComponent')
  filtersComponent: SortProductsComponent;

  constructor(protected productsService: CategoriesProductsService) { }

    sortFilters: any[] = [
      { name: 'Name (A to Z)', value: 'name' },
      { name: 'Price (low to high)', value: 'priceAsc' },
      { name: 'Price (high to low)', value: 'priceDes' }
    ];
    priceFilters: any[] = [
      { name: 'All', value: 'all', checked: true },
      { name: 'Price > 2000', value: 'more_2000', checked: false },
      { name: 'Price < 500', value: 'less_500', checked: false }
    ];

  ngOnInit() {
    this.displayProducts();
  }
  displayProducts() {
    this.productsService.getProducts().subscribe(product => {
      this.products = product;
      this.filteredProduct = product; });
    }

    onFilterChange(data) {
      if (data.type === 'category') {
      if (data.isChecked) {
          // tslint:disable-next-line:prefer-for-of
          for (let i = 0; i < data.filter.Products.length; i++) {
          this.filteredProduct.push(data.filter.Products[i]);
          }
        } else {
          this.filteredProduct =
          this.products.filter(x => {
            return x.CategoryId !== data.filter.Id; } );
        }
      } else if (data.type === 'price') {
        this.filteredProduct = this.products;
        if (data.isChecked) {
          const priceFilter = data.filter.value;
          if (priceFilter === 'all') {
              this.filteredProduct = this.products;
          } else if (priceFilter === 'more_2000' ) {

              this.filteredProduct = this.products.filter(x => x.Price > 2000);

          } else if (priceFilter === 'less_500' ) {

                this.filteredProduct = this.products.filter(x => x.Price < 500);
          }
        }
      }
    }

SortProductComponent:

   export class SortProductsComponent implements OnInit {
  categoriesList: Categories[];
  @Input()
  priceFilters: any[];
  // tslint:disable-next-line:no-output-on-prefix
  @Output()
  onFilterChange = new EventEmitter<any>();
  showFilters = true;
  sideShown = false;
  constructor(private categoriesService: CategoriesProductsService) { }

  ngOnInit() {
    this.displayCategories();
  }
  displayCategories() {
    this.categoriesService.getCategories().subscribe((data) => {
     this.categoriesList = data;

    });
  }
  onInputChange($event, filter, type) {
    const change = $event.target.checked ? 1 : -1;
    this.onFilterChange.emit({
      type,
      filter,
      isChecked: $event.target.checked,
      change
    });
}
}

HTML模板:

   <h5>Filter by categories</h5>
  <form >
      <div class="category-filter filter-wrapper" *ngFor = 'let filter of categoriesList'>
        <div class="custom-control custom-checkbox">
            <label class="fake-checkbox">
              <input type="checkbox" class="custom-control-input" checked (change)='onInputChange($event, filter, "category")'>
              <span class="custom-control-label">  {{filter.Name}}</span>
              <span></span>
            </label>
        </div>
    </div>
</form>
<h5>Filter by price</h5>
<form *ngIf = "showFilters">
    <div class="custom-filter filter-wrapper" *ngFor = 'let filter of priceFilters'>
        <label class="fake-checkbox">
          <input type="radio" name="price" [checked]='filter.checked' (click)='onInputChange($event, filter, "price")'>
          <span class="circle"><span class="fill"></span></span>
          <span class="label">{{filter.name}}</span>
          <span></span>
        </label>
    </div>
  </form>

产品类别:

export class Products {
  Id: number;
  Name: string;
  Description: string;
  DetailedDescription: string;
  Price: number;
  IsNewProduct: boolean;
  PromotionalProduct: boolean;
  Image: string;
  CategoryId: number;
}

我认为通过使用filter()方法,该方法将一个新数组返回给我,因此该数组上的过滤器只能运行一次。

我希望我的类别和价格过滤器可以像此页面一样工作:https://carlosroso.com/angular2-shop

欢迎任何帮助

1 个答案:

答案 0 :(得分:1)

是的,除非您希望每次用户更改过滤器时都重新获取产品,否则您将需要保留原始产品列表(未过滤)并使用它来过滤您的列表。

这是我的代码:

  ngOnInit(): void {
    this.productService.getProducts().subscribe(
      products => {
        this.products = products;
        this.filteredProducts = this.products;
      },
      error => this.errorMessage = <any>error
    );
  }

请注意,它将保留从服务返回的值,它们都在products(这是完整列表)和filteredProducts(这将始终是过滤后的列表)中。 (尽管它最初是所有产品的完整列表,但前提是该显示没有任何过滤器。)

然后,过滤器的始终是原始列表:

  performFilter(filterBy: string): IProduct[] {
    filterBy = filterBy.toLocaleLowerCase();
    return this.products.filter((product: IProduct) =>
      product.productName.toLocaleLowerCase().indexOf(filterBy) !== -1);
  }

请注意,它使用this.products.filter来确保始终从产品的完整列表中进行过滤。

您看起来会更像:

      this.filteredProduct = this.products.filter(x => {
        return x.CategoryId !== data.filter.Id; } );
    }