首页 > 解决方案 > 角度自定义管道和输入搜索自动完成

问题描述

我正在尝试使用任何字段值的自动完成进行输入,因此我创建了一个自定义管道。

我的问题是我该怎么做,因为我有一个显示我的 json 数据的组件和另一个包含自动完成输入的组件?

我应该使用@Input 和@Output 装饰器吗?

我是初学者 我不知道怎么做

非常感谢您的帮助

json.file

 {
        "boatType": "Semi-rigide",
        "img": "/assets/img/boat-img/semi-rigide.jpg",
        "longeur": 10,
        "largeur": 20,
        "tirantEau": 50,
        "equipage": false,
        "annexe": true
    },

table.component.html

<div class="search">
    <app-input #inputComponent></app-input>
</div>
<table>
   <caption>Statement Summary</caption>
    <thead>
        <tr>
            <th scope="col" class="toto">img</th>
            <th scope="col">Type de bateau</th>
            <th scope="col">longeur</th>
            <th scope="col">largeur</th>
            <th scope="col">tirant d'eau</th>
            <th scope="col">equipage</th>
            <th scope="col">annexe</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let boat of user | filter : inputComponent?.searchText">
            <td data-label="img"><img [src]="boat.img" alt="boat" class="img"></td>
            <td data-label="boat type">{{ boat.boatType }}</td>
            <td data-label="longeur">{{boat.longeur}} cm</td>
            <td data-label="largeur">{{boat.largeur}} cm</td>
            <td data-label="tirant d'eau">{{boat.tirantEau}} cm</td>
            <td data-label="equipage">{{boat.equipage ? "Oui" : "Non"}}</td>
            <td data-label="annexe">{{boat.annexe ? "Oui" : "Non"}}</td>
        </tr>
    </tbody>
</table>

input.component.html

 <input type="text" placeholder="Chercher un bateau.." [(ngModel)]="searchText">

过滤器管道

     import { Pipe, PipeTransform } from '@angular/core';
        
        @Pipe({
          name: 'filter'
        })
        export class FilterPipe implements PipeTransform {
        
        transform(items: any[], searchText: string): any[] {
    if (!items) return [];
    if (!searchText) return items;

    // TODO: need to improve this filter
    // because at this moment, only filter by boatType
    return items.filter(item => {
      return item.boatType.toLowerCase().includes(searchText.toLowerCase());
    });
  }
        
        }

标签: javascriptjsonangulartypescriptinput

解决方案


代码需要一些更改,因为您以不正确的方式使用这些工具。

但是,我进行了一些重构,并且使代码可以正常工作。

一个简短的解释和这里关于 stackblitz 的解决方案:https ://stackblitz.com/edit/angular-ivy-ybubhx?file=src/app/filter.pipe.ts

我不得不app-input使用#inputComponent. (还有其他方法可以得到这个)。

app.component.html

<div class="search">
  <!-- I create a variable on template called inputComponent -->
  <app-input #inputComponent></app-input> 
</div>
<table>
  <caption>Statement Summary</caption>
  <thead>
    <tr>
      <th scope="col">type</th>
      <!-- <th scope="col" class="toto">img</th> -->
      <th scope="col">longeur</th>
      <th scope="col">largeur</th>
      <th scope="col">tirant d'eau</th>
      <th scope="col">equipage</th>
      <th scope="col">annexe</th>
    </tr>
  </thead>
  <body>
    <!-- I pass the searchText string taken from inputComponent to our filter pipe -->
    <tr *ngFor="let boat of boats | filter : inputComponent?.searchText">
      <!-- <td data-label="img"><img [src]="boat.img" alt="boat" class="img"></td> -->
      <td data-label="boat type">{{ boat.boatType }}</td>
      <td data-label="longeur">{{boat.longeur}} cm</td>
      <td data-label="largeur">{{boat.largeur}} cm</td>
      <td data-label="tirant d'eau">{{boat.tirantEau}} cm</td>
      <td data-label="equipage">{{boat.equipage ? "Oui" : "Non"}}</td>
      <td data-label="annexe">{{boat.annexe ? "Oui" : "Non"}}</td>
    </tr>
  </tbody>
</table>

app.component.ts

import { Component, VERSION } from "@angular/core";

@Component({
  selector: "my-app",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent {
  // I use boats as payload to demonstrate the filter pipe functionality
  boats = [
    {
      boatType: "a1a12",
      img: "/assets/img/boat-img/semi-rigide.jpg",
      longeur: 10,
      largeur: 20,
      tirantEau: 50,
      equipage: false,
      annexe: true
    },
    {
      boatType: "EAEA",
      img: "/assets/img/boat-img/eaea.jpg",
      longeur: 10,
      largeur: 20,
      tirantEau: 50,
      equipage: false,
      annexe: true
    },
    {
      boatType: "bcbc",
      img: "/assets/img/boat-img/bcbc.jpg",
      longeur: 10,
      largeur: 20,
      tirantEau: 50,
      equipage: false,
      annexe: true
    },
    {
      boatType: "bcbc 2",
      img: "/assets/img/boat-img/bcbc.jpg",
      longeur: 10,
      largeur: 20,
      tirantEau: 50,
      equipage: false,
      annexe: true
    }
  ];
}

input.component.ts

import { Component, Input } from "@angular/core";

@Component({
  selector: "app-input",
  template: `
    <input
      type="text"
      placeholder="Chercher un bateau.."
      [(ngModel)]="searchText"
    />
  `,
  styles: [
    `
      h1 {
        font-family: Lato;
      }
    `
  ]
})
export class InputComponent {
  searchText: string;
}

filter.pipe.ts


import { Pipe, PipeTransform } from "@angular/core";

@Pipe({
  name: "filter"
})
export class FilterPipe implements PipeTransform {
  transform(items: any[], searchText: string): any[] {
    if (!items) return [];
    if (!searchText) return items;

    // TODO: need to improve this filter
    // because at this moment, only filter by boatType
    return items.filter(item => {
      return item.boatType.toLowerCase().includes(searchText.toLowerCase());
    });
  }
}


推荐阅读