【问题标题】:How to do a global search in angular 2?如何在 Angular 2 中进行全局搜索?
【发布时间】:2017-06-08 04:00:49
【问题描述】:

我是 angular2 的新开发者,我想在 json 对象数组中进行全局搜索。比如这个数组:

invoiceList = 
  [
    {
      invoiceNumber: 1234, 
      invoiceSupplier: "test", 
      invoiceStatus: "Import error", 
      invoiceCategory: "invoice with GR", 
      date: "22/01/2017", 
      amount : 134527
    },
    ...
  ];

我想像这样进行搜索:

这里的问题和困难在于:

  • 我只想根据某些值(例如:状态、供应商名称、编号...)进行搜索并显示其他字段(例如日期、净金额等)。
  • 我想根据某些值(例如:数量、供应商、日期和金额)按最终结果订购。而且我不知道如何在 angular2 中做到这一点。
  • 最后,我想在 angular2 中做一个“等效”的 ng-show 吗?我的意思是我只想在我们按下搜索按钮时显示表格,如果我们点击取消,它将删除它。

我知道在 angular 1 中这样做很简单,我们可以使用过滤器、'orderBy' 和类似的东西,但显然在 angular2 中,我们不能这样做,我非常困惑。你能帮我解决这个问题吗???

这是我的组件代码:

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

  @Component({
    selector: 'app-search',
    templateUrl: './search.component.html'
  })
  export class SearchComponent implements OnInit {

  invoiceList = [{invoiceNumber:  1234, invoiceSupplier : "test", invoiceStatus : "Import error", invoiceCategory: "invoice with GR", date : "22/01/2017", amount : 134527}, 
  {invoiceNumber:  15672, invoiceSupplier : "test11", invoiceStatus : "Import error", invoiceCategory: "invoice without PO", date : "02/01/2017", amount : 134.3},
  {invoiceNumber:  99863, invoiceSupplier : "test22", invoiceStatus : "Other Document", invoiceCategory: "invoice with GR", date : "10/12/2016", amount : 189},
  {invoiceNumber:  24561, invoiceSupplier : "test50", invoiceStatus : "Other Document", invoiceCategory: "invoice without PO", date : "15/01/2017", amount : -134527},
  ];


    constructor() { }

    ngOnInit() {
    }

  }

还有我的html代码:

  <form>
    <table>
      <tr>
        <td>Invoice Number :</td>
        <td>
          <input name="invoiceNumber">
        </td>

        <td>Invoice Supplier Name :</td>
        <td>
          <input name="invoiceSupplier">
        </td>
      </tr>

      <tr>
        <td>Invoice Status :</td>
        <td>
          <select name="invoiceStatus">

            <option></option>
            <option> Import error </option>
            <option> Invoice control required </option>
            <option>Rejected from SAP </option>
            <option>Other Document </option>
            <option> Invoice created manually in SAP </option>
            <option>To be integrated in SAP </option>
            <option> Integrated in SAP </option>
            <option> Booked in SAP </option>
            <option>Paid in SAP</option>
          </select>
        </td>

        <td>Invoice Category :</td>
        <td>

          <select name="invoiceCategory">
            <option></option>
            <option>Invoice with GR</option>
            <option>Invoice without GR</option>
            <option>Invoice without PO</option>

          </select>
        </td>
      </tr>

      <tr>
        <td>Order :</td>
        <td>
          <select name="order">

            <option> Number </option>
            <option> Supplier </option>
            <option> Date </option>
            <option> Net Amount </option>
          </select>
        </td>
      </tr>

      <tr>
        <td>
          <button type="submit">Search</button>
        </td>
        <td>
          <div class="detail">
            <button type="reset">Cancel</button>
          </div>
        </td>
      </tr>

    </table>
  </form>

我知道到目前为止我什么都没做,但我对 angular2 真的很陌生,我真的很困惑。你能帮我至少在组件部分吗???

提前谢谢你!

【问题讨论】:

  • 换句话说,我在这里要做的是根据 3 个值(3 个“变量”)进行 AND 搜索,但我不知道该怎么做......
  • 这个问题看起来与this question 非常相似。尝试使用答案之一中的示例调整您的代码。 (这是我在另一个帖子中提出的答案:stackoverflow.com/a/41738576/1471485

标签: angular typescript angular2-forms


【解决方案1】:

我建议使用Pipe 来过滤此类内容。

您的Pipe 可能如下所示:

  1. 检查传入变量
  2. 过滤您的发票
  3. 如果需要,请订购
@Pipe({
  name: 'filter'
})
export class FilterPipe implements PipeTransform {
  public transform(invoices: Invoice[], searchOptions: any): Invoice[] {
    if (!invoices || !invoices.length) return [];
    if (!searchOptions) return [];

    let filtered = invoices.filter(i => {
      return i &&
             (!searchOptions.number || i.invoiceNumber.toString().indexOf(searchOptions.number) >= 0) &&
             (!searchOptions.name || i.invoiceSupplier.toLowerCase().indexOf(searchOptions.name.toLowerCase()) >= 0) &&
             (!searchOptions.status || i.invoiceStatus === searchOptions.status) &&
             (!searchOptions.category || i.invoiceCategory === searchOptions.category);
    });

    let orderBy = searchOptions.orderBy;
    if (!orderBy) return filtered;

    /* credits for sorting goes to: 'Ankit Singh' ! :) */
    return filtered.sort((a, b) => {

      switch (orderBy) {
        default: return 0;

        case 'invoiceNumber':
        case 'amount':
          return a[orderBy] - b[orderBy];
        case 'invoiceSupplier':
        case 'invoiceStatus':
        case 'invoiceCategory':
          return (a[orderBy] == [a[orderBy], b[orderBy]].sort()[1] ? 1 : -1);
        case 'date': {
          const x = new Date(a.date.split('/').reverse().join('/'));
          const y = new Date(b.date.split('/').reverse().join('/'));
          return x.getTime() - y.getTime();
        }
      }
   });
  }
}

并通过以下方式使用Pipe

<div class="row" *ngFor="let invoice of invoiceList | filter:searchOptions">
  <div>{{ invoice.invoiceNumber }}</div>
  <div>{{ invoice.invoiceSupplier }}</div>
  <div>{{ invoice.date }}</div>
  <div>{{ invoice.amount }}</div>
</div>

那些searchOptions 是来自我们表单的对象:

<md-input-container>
  <input mdInput ngModel name="name" placeholder="Invoice supplier name">
</md-input-container>

<md-select placeholder="Invoice status" ngModel name="status">
  <md-option *ngFor="let status of statusArray" [value]="status.val">
    {{ status.name}}
  </md-option>
</md-select>

<md-select placeholder="Invoice category" ngModel name="category">
  <md-option *ngFor="let category of categoryArray" [value]="category.val">
    {{ category.name}}
  </md-option>
</md-select>

<md-select placeholder="order by" ngModel name="orderBy">
  <md-option *ngFor="let key of invoiceKeyArray" [value]="key.val">
    {{ key.name }}
  </md-option>
</md-select>

<button md-raised-button color="primary" (click)="searchOptions = f.value">search</button>
<button md-raised-button color="accent" (click)="resetForm(f);">reset</button>

现场演示:http://plnkr.co/edit/VPTnIOpieKt3YLqsEncr?p=preview

【讨论】:

    【解决方案2】:

    完成!! - see@PLUNKER

    @Component({
      selector: 'app-search',
      templateUrl: 'src/search.component.html'
    })
    export class SearchComponent{
    
     invoiceList = [
      {invoiceNumber:  1234, invoiceSupplier : "test", invoiceStatus : "Import error", invoiceCategory: "invoice with GR", date : "22/01/2017", amount : 134527}, 
      {invoiceNumber:  15672, invoiceSupplier : "test11", invoiceStatus : "Import error", invoiceCategory: "invoice without PO", date : "02/01/2017", amount : 134.3},
      {invoiceNumber:  99863, invoiceSupplier : "test22", invoiceStatus : "Other Document", invoiceCategory: "invoice with GR", date : "10/12/2016", amount : 189},
      {invoiceNumber:  24561, invoiceSupplier : "test50", invoiceStatus : "Other Document", invoiceCategory: "invoice without PO", date : "15/01/2017", amount : -134527},
     ];
    
     invoiceCats = [];
     invoiceStatuses = [];
     invoiceNumbers = [];
     invoiceFields = Object.keys(this.invoiceList[0]);
    
     invoiceStatus = "";
     invoiceCategory = "";
     invoiceNumber;
     invoiceSupplier;
     order = this.invoiceFields[0];
    
     searchResults = [];
    
     constructor() { 
       this.invoiceList.forEach(i => {
         if(this.invoiceCats.indexOf(i.invoiceCategory) === -1) {
          this.invoiceCats.push(i.invoiceCategory);
         }
    
         if(this.invoiceStatuses.indexOf(i.invoiceStatus) === -1) {
          this.invoiceStatuses.push(i.invoiceStatus);
         }
    
         this.invoiceNumbers.push(i.invoiceNumber);
       })
     }
    
     ngOnInit() {
     }
    
     searchNow(e) {
       e.preventDefault();
       this.searchResults = this.invoiceList.filter(i => {
         return (this.invoiceStatus ? i.invoiceStatus === this.invoiceStatus : true) 
            &&  (this.invoiceNumber ? i.invoiceNumber === this.invoiceNumber : true)
            &&  (this.invoiceSupplier ? i.invoiceSupplier === this.invoiceSupplier : true)
            &&  (this.invoiceCategory ? i.invoiceCategory === this.invoiceCategory : true)
       }).sort((a, b) => {
          if(['invoiceNumber', 'amount'].indexOf(this.order) > -1) return a[this.order] - b[this.order];
          if(['invoiceSupplier', 'invoiceStatus', 'invoiceCategory'].indexOf(this.order) > -1) return (a[this.order] == [a[this.order], b[this.order]].sort()[1] ? 1 : -1);
          if(this.order === 'date') {
            const x = new Date(a.date.split('/').reverse().join('/'));
            const y = new Date(b.date.split('/').reverse().join('/'));
            return x.getTime() - y.getTime();
          }
       })
     }
    
    }
    

    注意:构造函数中的代码只是为了生成元数据。

     <form (submit)="searchNow($event)">
        <table>
          <tr>
            <td>Invoice Number :</td>
            <td>
              <input name="invoiceNumber" [(ngModel)]="invoiceNumber" type="number">
            </td>
    
            <td>Invoice Supplier Name :</td>
            <td>
              <input name="invoiceSupplier" [(ngModel)]="invoiceSupplier" type="text">
            </td>
          </tr>
    
          <tr>
            <td>Invoice Status :</td>
            <td>
              <select name="invoiceStatus" [(ngModel)]="invoiceStatus">
                <option value="">Any</option>
                <option *ngFor="let iS of invoiceStatuses" [value]="iS">{{iS}}</option>
              </select>
            </td>
    
            <td>Invoice Category :</td>
            <td>
    
              <select name="invoiceCategory" [(ngModel)]="invoiceCategory">
                <option value="">Any</option>
                <option *ngFor="let iC of invoiceCats" [value]="iC">{{iC}}</option>
              </select>
            </td>
          </tr>
    
          <tr>
            <td>Order By:</td>
            <td>
              <select name="order" [(ngModel)]="order">
                <option *ngFor="let iF of invoiceFields" [value]="iF">{{iF}}</option>
              </select>
            </td>
          </tr>
    
          <tr>
            <td>
              <button type="submit">Search</button>
            </td>
            <td>
              <div class="detail">
                <button type="reset">Cancel</button>
              </div>
            </td>
          </tr>
    
        </table>
      </form>
    
      <div>
        <ul>
          <li *ngFor="let i of searchResults">Number: {{i.invoiceNumber}},  Supplier: {{i.invoiceSupplier}}, Date: {{i.date}}</li>
        </ul>
      </div>
    

    注意:Angular2 中的表单有很多(如果不是上百种)玩法,你可以使用任何你喜欢的方法,我只使用了最简单的一种。

    【讨论】:

      【解决方案3】:

      不完整,但给你基地......

      import { Component, OnInit } from '@angular/core';
      
      export class Invoice {
          invoiceNumber: number;
          invoiceSupplier: string;
          invoiceStatus: string;
          invoiceCategory: string;
          date: string;
          amount: number
      }
      
      @Component({
          moduleId: module.id,
          selector: 'my-app',
          template: `
              <div></div>
          `,
          styleUrls: []
      })
      
      export class AppComponent implements OnInit {
      
          ngOnInit(): void {
      
              this.invoiceList = [ {invoiceNumber: 1231, invoiceSupplier: "test1", invoiceStatus: "Import error3", invoiceCategory: "invoice with GR1", date: "22/01/2017", amount : 134527 },
                                   {invoiceNumber: 1232, invoiceSupplier: "test1", invoiceStatus: "Import error2", invoiceCategory: "invoice with GR2", date: "22/01/2017", amount : 134527 },
                                   {invoiceNumber: 1233, invoiceSupplier: "test2", invoiceStatus: "Import error1", invoiceCategory: "invoice with GR1", date: "22/01/2017", amount : 134527 },
                                   {invoiceNumber: 1234, invoiceSupplier: "test3", invoiceStatus: "Import error3", invoiceCategory: "invoice with GR3", date: "22/01/2017", amount : 134527 },
                                ];
      
              //this.invoiceFilter.invoiceNumber = 1234;
              //this.invoiceFilter.invoiceSupplier = "test2";
              this.invoiceFilter.invoiceCategory = "invoice with GR2";
      
              let filterdeInvoices = this.filterInvoices(this.invoiceList, this.invoiceFilter);
              console.log(filterdeInvoices);
              this.fieldToSortBy = "invoiceNumber";
              let sortedInvoices = this.sortInvoices(filterdeInvoices, this.fieldToSortBy);
              console.log(sortedInvoices);
          }
      
          invoiceFilter = new Invoice();
          fieldToSortBy: string;
          invoiceList: Invoice[];
      
          filterInvoices(invoiceList:Invoice[], invoiceFilter: Invoice): Invoice[]         {        
              return invoiceList.filter((invoice) => (invoiceFilter.invoiceNumber ? invoiceFilter.invoiceNumber === invoice.invoiceNumber : true) &&
                                                     (invoiceFilter.invoiceSupplier ? invoiceFilter.invoiceSupplier === invoice.invoiceSupplier : true) &&
                                                     (invoiceFilter.invoiceStatus ? invoiceFilter.invoiceStatus === invoice.invoiceStatus : true) &&
                                                     (invoiceFilter.invoiceCategory ? invoiceFilter.invoiceCategory === invoice.invoiceCategory : true));
          }
      
          sortInvoices(invoiceList:Invoice[], fieldToSortBy: string): Invoice[] {
              return invoiceList.sort((inv1, inv2) => (inv1[fieldToSortBy] > inv2[fieldToSortBy] ? 1 : -1));
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-09-15
        • 2016-11-14
        • 2011-11-04
        • 1970-01-01
        • 2021-05-17
        • 1970-01-01
        • 2011-12-18
        • 2021-05-10
        相关资源
        最近更新 更多