NgbHighlight: ограничение до одной выделенной части построчно - PullRequest
0 голосов
/ 05 июля 2019

Я использую NgbHighlight, чтобы позволить пользователю просматривать список. Моя проблема с выделением результата. Я хочу выделить только первый матч.

Я использую самые основы, описанные здесь: https://ng -bootstrap.github.io / # / components / typeahead / examples

Код: https://ng -bootstrap.github.io / stackblitzes / typeahead / http / stackblitz.html

Список: ['ABCD AAAA ABCD', 'BBBB ABCD BBBB', 'CCCC CCCC CCCC'];

Поиск: 'ABCD'

Вывод, который я хочу: ' ABCD AAAA ABCD' 'BBBB ABCD BBBB'

На выходе я получаю: ' ABCD AAAA ABCD ' 'BBBB ABCD BBBB'

Что я должен сделать, чтобы ограничить подсветку первой частью?

Спасибо за помощь:)

Редактировать: простой пример

HTML

<div class="form-group">
  <label for="typeahead-http">Search for a wiki page:</label>
  <input id="typeahead-http" type="text" class="form-control" [class.is-invalid]="searchFailed" [(ngModel)]="model" [ngbTypeahead]="search" placeholder="Wikipedia search" />
  <span *ngIf="searching">searching...</span>
  <div class="invalid-feedback" *ngIf="searchFailed">Sorry, suggestions could not be loaded.</div>
</div>

машинопись

import {Component, Injectable} from '@angular/core';
import {HttpClient, HttpParams} from '@angular/common/http';
import {Observable, of} from 'rxjs';
import {catchError, debounceTime, distinctUntilChanged, map, tap, switchMap} from 'rxjs/operators';

const WIKI_URL = 'https://en.wikipedia.org/w/api.php';
const PARAMS = new HttpParams({
  fromObject: {
    action: 'opensearch',
    format: 'json',
    origin: '*'
  }
});

@Injectable()
export class WikipediaService {
  constructor(private http: HttpClient) {}

  search(term: string) {
    if (term === '') {
      return of([]);
    }

    return this.http
      .get(WIKI_URL, {params: PARAMS.set('search', term)}).pipe(
        map(response => response[1])
      );
  }
}

@Component({
  selector: 'ngbd-typeahead-http',
  templateUrl: './typeahead-http.html',
  providers: [WikipediaService],
  styles: [`.form-control { width: 300px; display: inline; }`]
})
export class NgbdTypeaheadHttp {
  model: any;
  searching = false;
  searchFailed = false;

  constructor(private _service: WikipediaService) {}

  search = (text$: Observable<string>) =>
    text$.pipe(
      debounceTime(300),
      distinctUntilChanged(),
      tap(() => this.searching = true),
      switchMap(term =>
        this._service.search(term).pipe(
          tap(() => this.searchFailed = false),
          catchError(() => {
            this.searchFailed = true;
            return of([]);
          }))
      ),
      tap(() => this.searching = false)
    )
}

Ответы [ 2 ]

1 голос
/ 08 июля 2019

Чтобы не касаться кода ngb-typeahead, я исправил свой CSS. Не самое лучшее решение, но, по крайней мере, оно работает визуально.

Вот сгенерированный HTML с помощью ngb-typeahead (нетронутый, я только что удалил комментарии). Критерий поиска: 'ABCD'

<ngb-highlight ng-reflect-result="'ABCD AAAA ABCD" ng-reflect-term="act">
    <span class="ngb-highlight">ABCD</span>
    &nbsp;AAAA&nbsp;
    <span class="ngb-highlight">ABCD</span>
</ngb-highlight>

Итак, мое решение:

.ngb-highlight {
  font-weight: normal !important;
}

ngb-highlight .ngb-highlight:first-child {
  font-weight: bold !important;
}

Как видите, не самый красивый, но, по крайней мере, мне не нужно ничего менять в будущем.

В любом случае, спасибо за помощь всем!

0 голосов
/ 06 июля 2019

NgbHighlight не может этого сделать.Вы можете легко реализовать необходимый компонент на основе исходного кода NgbHighlight .Это крошечный компонент и небольшое изменение.Вам просто нужно немного изменить регулярное выражение, чтобы разделить его только при первом появлении термина

  ngOnChanges(changes: SimpleChanges) {
    const result = toString(this.result);

    const terms = Array.isArray(this.term) ? this.term : [this.term];
    const escapedTerms = terms.map(term => regExpEscape(toString(term)))
        .map(term => `${term}(.+)`)
        .filter(term => term);


    this.parts = escapedTerms.length ? result.split(new RegExp(`(${escapedTerms.join('|')})`, 'gmi')) : [result];
  }

код никогда не тестировался (: не уверен, что он будет работать с несколькими терминами

...