【问题标题】:Angular filtering items in array by 2 criteria按 2 个标准对数组中的项目进行角度过滤
【发布时间】:2019-02-19 20:15:54
【问题描述】:

我创建了排序侧边栏,它根据类别和价格过滤我的产品列表。按类别过滤可以正常工作。 我在根据产品价格进行过滤时遇到问题。如果我将类别设置为“Smartfons”并过滤价格高于 2000 的产品,在我的情况下它将正确返回 Iphone X:@​​987654322@ 但是当我将过滤器更改为“全部”时,我有一部手机,它应该返回 3 部手机:

    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);
          }
        }
      }
    }

排序产品组件:

   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

欢迎任何帮助

【问题讨论】:

    标签: angular typescript filter


    【解决方案1】:

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

    我的代码如下所示:

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

    请注意,它在products(完整列表)和filteredProducts(始终是过滤列表)中保留了服务返回的值。 (虽然它最初是产品的完整列表,假设显示开始时没有过滤器。)

    那么过滤器的source永远是原始列表:

      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; } );
        }
    

    【讨论】:

    • 我更新了您推荐的帖子,但价格过滤器仍有问题:zapodaj.net/b7883f722551d.png.html
    • 你有什么问题?
    • 选择所有类别后,我的价格过滤器工作正常。当我选择“Smartfons”类别并选择低于 500 的过滤器价格时,它向我显示了整个列表中的产品,应该显示一个空列表,因为在这个选定的类别中没有这样的产品。就像我在上面放的这张照片一样。
    • 尝试通读onFilterChange 方法的每一行,并确保您在每一步都使用适当的数据集。我不太了解该代码试图在每一行中实现什么以提供更多帮助。
    猜你喜欢
    • 1970-01-01
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-16
    • 1970-01-01
    • 2017-09-01
    • 1970-01-01
    相关资源
    最近更新 更多