Angular에서 검색 필터 생성하기

한 장면을 고려하면, 이 장면에서 우리는 긴 데이터가 UI에 사용자에게 표시됩니다.만약 검색 기능을 제공하지 않는다면, 사용자가 이 긴 목록에서 특정한 키워드를 검색하는 것은 매우 번거로울 것이다.따라서 사용자의 생활을 편리하게 하기 위해 우리는 보통 사용자 인터페이스에서 검색 필터를 실현한다.
그렇다면 지금의 문제는 어떻게 그것을 실시할 것인가?그런데 이게 쉬워요.😉 우리는 필터 하나만 필요합니다. 필터는 그룹을 입력으로 하고, 우리가 제공한 용어에 따라 이 그룹의 서브집합을 되돌려줍니다.Angular에서 이러한 데이터를 다른 형식으로 바꾸는 방법은 Pipes 에서 실현된다.구현을 시작하기 전에 먼저 pipes에 대해 알아보겠습니다.

각도가 있는 파이프


파이프는 데이터를 입력으로 수신하고 필요한 출력으로 변환합니다.파이핑은 HTML 템플릿 표현식 및 어셈블리에서 사용할 수 있습니다.Angular는 CurrencyPipe, DatePipe, DecimalPipe 등 내장 파이프를 제공합니다. 실제 응용 프로그램을 보려면 아래 코드 부분을 보십시오.
dateObj = Date.now();

// HTML template expression syntax using pipe operator (|)
{{ dateObj | date }}               // output is 'Jun 15, 2015'
{{ dateObj | date:'medium' }}      // output is 'Jun 15, 2015, 9:43:11 PM'
{{ dateObj | date:'shortTime' }}   // output is '9:43 PM'
{{ dateObj | date:'mm:ss' }}       // output is '43:11'

// Using in component
constructor(private datePipe: DatePipe) { 
    console.log(datePipe.transform(Date.now(),'yyyy-MM-dd'));
    //2019-07-22
}
파이프는 두 가지 유형이 있는데 그것이 바로 순수함과 불순함이다.각 파이프에 대한 자세한 내용은 visit this link 을 참조하십시오.

검색 필터 구현


1. 필터 파이프 생성하기


필터 코드로 파이프를 채우자.이 코드를 복사하여 붙여넣기filter.pipe.ts:
// filter.pipe.ts

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

@Pipe({ name: 'appFilter' })
export class FilterPipe implements PipeTransform {
  /**
   * Pipe filters the list of elements based on the search text provided
   *
   * @param items list of elements to search in
   * @param searchText search string
   * @returns list of elements filtered by search text or []
   */
  transform(items: any[], searchText: string): any[] {
    if (!items) {
      return [];
    }
    if (!searchText) {
      return items;
    }
    searchText = searchText.toLocaleLowerCase();

    return items.filter(it => {
      return it.toLocaleLowerCase().includes(searchText);
    });
  }
}
이 파이프 정의는 다음과 같은 관건을 보여 줍니다.
  • 파이프는 파이프 메타데이터로 장식된 종류이다.
  • pipe류는 PipeTransform 인터페이스를 실현하는transform 방법으로 이 방법은 입력 값을 받아들여 선택할 수 있는 매개 변수와 함께 - 변환된 값을 되돌려줍니다.필터 파이프에는 2개의 입력 - 하나array와 하나search text가 필요합니다.
  • Angular가 파이프라는 것을 알려주기 위해 코어 Angular 라이브러리에서 가져온 @Pipe decorator 을 적용했습니다.
  • @Pipe 데코더를 사용하면 템플릿 표현식에 사용할 파이프 이름을 정의할 수 있습니다.유효한 JavaScript 식별자여야 합니다.우리의 파이프 이름은 appFilter 입니다.
  • 2, 파이프 사용


    파이프를 사용하려면 우선 응용 프로그램 모듈로 가져와야 합니다.우리의 app.module.ts 파일은 다음과 같습니다.
    // app.module.ts
    
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    
    import { AppComponent } from './app.component';
    
    import { FilterPipe } from './pipes/filter.pipe'; // -> imported filter pipe
    
    @NgModule({
      declarations: [
        AppComponent,
        FilterPipe // -> added filter pipe to use it inside the component
      ],
      imports: [
        BrowserModule,
        FormsModule
      ],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
    현재 우리는 App Component 에서 필터를 사용할 수 있다.만약에 우리app.component.html에 입력 상자가 있다고 가정하면 우리는 그 중에서 searchText와 목록을 입력할 수 있다. 이 목록은 이것pipe을 이용하여 결과를 필터할 수 있다.
    <!-- app.component.html -->
    
    <div class="content" role="main">
      <div class="card">
        <div class="form-group">
          <label for="search-text">Search Text</label>
          <input type="email" class="form-control" id="search-text" aria-describedby="search-text" 
            [(ngModel)]="searchText" placeholder="Enter text to search" 
            autofocus>
        </div>
        <ul class="list-group list-group-flush">
          <!-- results of ngFor is passed to appFilter with argument searchText -->
          <li class="list-group-item" *ngFor="let c of characters | appFilter: searchText">
            {{c}}
          </li>
        </ul>
      </div>
    </div>
    
    // app.component.ts
    
    import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./app.component.scss']
    })
    export class AppComponent {
      title = 'angular-text-search-highlight';
      searchText = '';
      characters = [
        'Ant-Man',
        'Aquaman',
        'Asterix',
        'The Atom',
        'The Avengers',
        'Batgirl',
        'Batman',
        'Batwoman',
        ...
      ]
    }
    
    그렇습니다!이제 응용 프로그램을 실행할 때 다음 출력을 볼 수 있습니다.
    하지만 헤이!저희 검색 결과가 처음에 나왔던 것처럼 튀어나오지 않았어요.😟Pipesangular에서 전달된 데이터만 필요한 출력으로 변환하기 때문이다.연관된 HTML은 작동하지 않습니다.검색 결과를 강조 표시하려면 HTML을 사용하여 섹션searchText을 강조 표시해야 합니다.이것은 Directives를 사용하여 실현할 수 있다.

    각도 명령


    각도 명령은 새로운 구문을 제공하여 HTML의 기능을 확장합니다.명령에는 다음 세 가지 유형이 있습니다.
  • 구성 요소 - 템플릿이 있는 명령입니다.
  • 구조 명령 - DOM 요소를 추가하고 삭제하여 DOM 레이아웃을 변경합니다.
  • 속성 명령 - 요소, 구성 요소 또는 기타 명령의 모양 또는 동작을 변경합니다.
  • 포괄 지령은 본문의 범위를 넘어섰다.각도 명령에 대한 자세한 내용을 알고 싶다면visit this link.

    응용 프로그램에서 명령 실행


    우리의 예에서, 우리는 attribute directive 결과 목록의 searchText 을 강조 표시할 것이다.

    1. 강조 명령 만들기


    속성 명령은 최소한 @directive 주석을 사용하는 컨트롤러 클래스를 구축해야 합니다. 이 클래스는 속성을 표시하는 선택기를 지정합니다.컨트롤러 클래스는 필요한 지령 행위를 실현한다.
    우리는 하이라이트로 표시된 코드로 명령을 채웁니다.이 코드를 복사하여 붙여넣기highlight.pipe.ts:
    // highlight.directive.ts
    
    import { Directive, Input, SimpleChanges, Renderer2, ElementRef, OnChanges } from '@angular/core';
    
    @Directive({
      selector: '[appHighlight]'
    })
    export class HighlightDirective implements OnChanges {
      @Input() searchedWord: string; // searchText
      @Input() content: string; // HTML content
      @Input() classToApply: string; //class to apply for highlighting
      @Input() setTitle = false; //sets title attribute of HTML
    
      constructor(private el: ElementRef, private renderer: Renderer2) { }
    
      ngOnChanges(changes: SimpleChanges): void {
        if (!this.content) {
          return;
        }
    
        if (this.setTitle) {
          this.renderer.setProperty(
            this.el.nativeElement,
            'title',
            this.content
          );
        }
    
        if (!this.searchedWord || !this.searchedWord.length || !this.classToApply) {
          this.renderer.setProperty(this.el.nativeElement, 'innerHTML', this.content);
          return;
        }
    
        this.renderer.setProperty(
          this.el.nativeElement,
          'innerHTML',
          this.getFormattedText()
        );
      }
    
      getFormattedText() {
        const re = new RegExp(`(${this.searchedWord})`, 'gi');
        return this.content.replace(re, `<span class="${this.classToApply}">$1</span>`);
      }
    }
    

    The logic is to manipulate the current HTML element by adding <span> tag in between the searchText and applying the highlighting class to it.


    2. 사용 명령


    파이프를 사용하려면 우선 응용 프로그램 모듈로 가져와야 합니다.우리의 app.module.ts 파일은 다음과 같습니다.
    // app.module.ts
    
    import { BrowserModule } from '@angular/platform-browser';
    import { NgModule } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    
    import { AppComponent } from './app.component';
    
    import { HighlightDirective } from './directives/highlight.directive'; // ->  imported directive
    import { FilterPipe } from './pipes/filter.pipe';
    
    @NgModule({
      declarations: [
        AppComponent,
        HighlightDirective, // -> added directive
        FilterPipe
      ],
      imports: [
        BrowserModule,
        FormsModule
      ],
      providers: [],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    
    이 명령은 HTML 파일에서 사용하기 위해 일반 HTML 속성과 모든 매개 변수로 추가됩니다.그것은 보기에 이렇다.
    <!-- app.component.html -->
    
    <div class="content" role="main">
      <div class="card">
        <div class="form-group">
          <label for="search-text">Search Text</label>
          <input type="email" class="form-control" id="search-text" aria-describedby="search-text" 
            [(ngModel)]="searchText" placeholder="Enter text to search" 
            autofocus>
        </div>
        <ul class="list-group list-group-flush">
          <li class="list-group-item" *ngFor="let c of characters | appFilter: searchText"
            appHighlight [searchedWord]="searchText" [content]="c"  
            [classToApply]="'font-weight-bold'" [setTitle]="'true'">
            {{c}}
          </li>
        </ul>
      </div>
    </div>
    
    이제 필요한 출력을 볼 수 있습니다!😌
    너는 나의 GitHub repo을 보고 이 문장의 완전한 실현을 이해할 수 있다.
    안녕히 가세요.내 다음 댓글까지.😋

    좋은 웹페이지 즐겨찾기