Angular 8 => 条件:显示其他值

Angular 8 => Condition : show an else value

如果在我的查询中找不到结果,我正在尝试过滤默认值。

我试过使用 ng-template,但我就是做不到。


不用写,看图更好理解:

这是我成功的过滤器:一旦我在搜索框中过滤它们,它就会正确显示我的数据。


但是,如果我尝试输入无效数据,如下所示

它只是 returns 我一个空 html table.

这不是我想要实现的。我希望它显示一条消息:未找到数据。

请问我该怎么做?


这是我的源代码 :

分量 :

import {Component, OnInit} from '@angular/core';
import {IProduct} from './product';

@Component({
  selector: 'pm-products',
  templateUrl: './product-list.component.html',
  styleUrls: ['./product-list.component.css']
})

export class ProductListComponent implements OnInit {

  ///////////////////////////////////// PROPERTIES //////////////////////////////////////

  // String Interpolation
  pageTitle = 'Product List';

  // Property binding
  imageWidth = 50;
  imageMargin = 2;

  // Event binding
  showImage = false;

  // Two-way binding
  // listFilter = 'cart';

  // Filter products
  private _listFilter: string;

  // Filter Products Array
  filteredProducts: IProduct[];

  ///////////////////////////////////// CONSTRUCTOR //////////////////////////////////////

  constructor() {
    this.filteredProducts = this.products;
    this.listFilter = 'cart';
  }

  /////////////////////////////////// GETTERS/SETTERS ///////////////////////////////////

  get listFilter(): string {
    return this._listFilter;
  }

  set listFilter(value: string) {
    this._listFilter = value;
    /***
     * If there is a list of filtered value, show the list of the filtered values => this.performFilter(this.listFilter)
     * Else, (if there is no filtered) return the whole set of products
     */
    this.filteredProducts = this.listFilter ? this.performFilter(this.listFilter) : this.products;
  }

  /////////////////////////////////////// METHODS ///////////////////////////////////////

  // Get Products
  products: IProduct[] = [
    {
      productId: 2,
      productName: 'Garden Cart',
      productCode: 'GDN-0023',
      releaseDate: 'March 18, 2019',
      description: '15 gallon capacity rolling garden cart',
      price: 32.99,
      starRating: 4.2,
      imageUrl: 'assets/images/garden_cart.png'
    },
    {
      productId: 5,
      productName: 'Hammer',
      productCode: 'TBX-0048',
      releaseDate: 'May 21, 2019',
      description: 'Curved claw steel hammer',
      price: 8.9,
      starRating: 4.8,
      imageUrl: 'assets/images/hammer.png'
    },
  ];

  performFilter(filterBy: string): IProduct[] {
    /**
     * filterBy result => to lower case. => case insensitive comparison.
     * Return a new array of the filtered productS by the product name,
     * by checking if that product name given is an index of the an element in the product array.
     */
    filterBy = filterBy.toLowerCase(); // 1.
    return  this.products.filter((product: IProduct) => product.productName.toLowerCase().indexOf(filterBy) !== - 1); // 2.
  }

  toggleImage = (): void => {
    this.showImage = !this.showImage;
  }

  ////////////////////////////////// LIFECYCLE HOOKS ///////////////////////////////////

  ngOnInit(): void {
    console.log('hello');
  }
}

HTML

<div class="card">

  <div class="card-header">{{pageTitle}}</div>

  <!-- CARD -->
  <div class="card-body">
    <div class="row">
      <div class="col-md-2"> Filter by:</div>
      <div class="col-md-4">
        <input [(ngModel)]="listFilter" type="text"/>
      </div>
    </div>
    <div class="row">
      <div class="col-md-6">
        <h4>Filtered by: {{listFilter}} </h4>
      </div>
    </div>
    <!-- ./CARD -->

    <!-- TABLE -->
    <div class="table-responsive">
      <table *ngIf="products && products.length" class="table">
        <thead>
        <tr>
          <th>
            <button (click)="toggleImage()" class="btn btn-primary">{{showImage ? "Hide" : "Show"}} image</button>
          </th>
          <th>Product</th>
          <th>Code</th>
          <th>Available</th>
          <th>Price</th>
          <th>5 Star Rating</th>
        </tr>
        </thead>
        <tbody>
        <tr *ngFor="let product of filteredProducts">
          <td><img *ngIf="showImage" [src]="product.imageUrl" [title]="product.productName"
                   [style.width.px]="imageWidth" [style.margin.px]="imageMargin" alt=""></td>
          <td>{{product.productName}}</td>
          <td>{{product.productCode | lowercase | convertToSpaces: '-'}}</td>
          <td>{{product.releaseDate}}</td>
          <td>{{product.price | currency: 'EUR':'symbol':'2.2-2'}}</td>
          <td>{{product.starRating}}</td>
        </tr>
        </tbody>
      </table>
    </div>
    <!-- ./TABLE -->
  </div>
</div>

请保重身体。

也许只要在您想显示消息的地方添加一个 *ngIf="!filteredProducts.length"

例如


<tr *ngFor="let product of filteredProducts">
    //Your table stuff
</tr>
<tr *ngIf="!filteredProducts.length">
     <td colspan="6">No data found</td>
</tr>

You have to add tr contains string no data found after ngfor tr

  <tr *ngFor="let product of filteredProducts">
          <td><img *ngIf="showImage" [src]="product.imageUrl" [title]="product.productName"
                   [style.width.px]="imageWidth" [style.margin.px]="imageMargin" alt=""></td>
          <td>{{product.productName}}</td>
          <td>{{product.productCode | lowercase | convertToSpaces: '-'}}</td>
          <td>{{product.releaseDate}}</td>
          <td>{{product.price | currency: 'EUR':'symbol':'2.2-2'}}</td>
          <td>{{product.starRating}}</td>
        </tr>

<tr *ngIf="filteredProducts.length === 0 " >
<td colspan="6" >Your message here </td>
</tr>

您可以简单地添加一个仅在列表为空且搜索栏有任何值时才出现的行。像这样:

 <tr *ngFor="let product of filteredProducts">...</tr>

 <tr col-span ="6" *ngIf="!filteredProducts.length && listFilter.length"> uh oh, 
 could not find what you searched for</tr>