Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 01.01.2017, 23:20
Интересующийся
Отправить личное сообщение для Digan Посмотреть профиль Найти все сообщения от Digan
 
Регистрация: 08.10.2012
Сообщений: 12

Angular 2. Фильтрация с RxJs
Хочу реализовать простейший фильтр списка. За основу взял один из туториалов из документации. Но мне нужно немного изменить поведение: если в туториале с пустым текстовым полем список получается пустой, то мне нужно, чтобы в этом в списке после загрузки страницы выводились все элементы массива.

Вот темплейт:
<div>
    <input #searchBox id="search-box" type="text" (keyup)="search(searchBox.value)"/>
    <ul>
        <li *ngFor="let contact of displayedContacts | async" class="contact">
            <span>{{contact.name}}</span>
        </li>
    </ul>
</div>


Часть кода компонента:
contacts: Array<any>;
displayedContacts: Observable<any[]>;
private searchTerms = new Subject<string>();
...
this.displayedContacts = this.searchTerms
      .debounceTime(300)
      .distinctUntilChanged()
      .switchMap(term => this.filterContacts(term))
      .catch(error => {
        console.log(error);
        return Observable.of<any[]>([]);
      });
...
search(term: string): void {
    this.searchTerms.next(term);
  }


То что мне нужно пока получается добиться с помощью такого кода:
setTimeout(()=>{
        this.searchTerms.next("");
      }, 1500);


Но должен быть нормальный способ это сделать.
Ответить с цитированием
  #2 (permalink)  
Старый 02.01.2017, 07:44
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

Digan,
Метод filterContacts еще покажи. В ngOnInit компонента не получится вынести прокидывание нужного тебе значения?
this.searchTerms.next("");

Или делай через BehaviorSubject с установкой нужного тебе значения при создании.
Ответить с цитированием
  #3 (permalink)  
Старый 02.01.2017, 10:49
Интересующийся
Отправить личное сообщение для Digan Посмотреть профиль Найти все сообщения от Digan
 
Регистрация: 08.10.2012
Сообщений: 12

Сообщение от destus Посмотреть сообщение
Или делай через BehaviorSubject с установкой нужного тебе значения при создании.
Спасибо. Это действительно помогло.
private searchTerms = new BehaviorSubject<string>("");

Получается Subject получается нельзя также инициализировать.

Общий вопрос по rxJs. За счет чего при использовании этой библиотеки не блокируется страница при перестройки dom?
У меня в списке 3 тыс. элементов. Если rxJs не использовать, то при фильтрации происходит кратковременное но подвисание при перестройке dom.
Ответить с цитированием
  #4 (permalink)  
Старый 02.01.2017, 18:16
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

Digan,
Цитата:
Получается Subject получается нельзя также инициализировать
BehaviorSubject хранит последнее значение и передает его подписавшемуся обсерверу.
Цитата:
У меня в списке 3 тыс. элементов. Если rxJs не использовать, то при фильтрации происходит кратковременное но подвисание при перестройке dom.
А как фильтруешь? При каждом нажатии клавиши? Все такие такие вещи как debounceTime используются не просто так, а чтобы пользователь сначала написал что ищет, а затем будет обращение к апи, фильтрации какой-то коллекции и т.д. Если посмотреть в исходный код, то никакой магии там нет. Есть какая-то предикатная функция, которая выполняется для каждого элемента в потоке https://github.com/ReactiveX/rxjs/bl...ator/filter.ts.

Ну и не забываем использовать trackBy вместе с директивой ngFor.
Ответить с цитированием
  #5 (permalink)  
Старый 03.01.2017, 13:25
Интересующийся
Отправить личное сообщение для Digan Посмотреть профиль Найти все сообщения от Digan
 
Регистрация: 08.10.2012
Сообщений: 12

Сообщение от destus Посмотреть сообщение
Digan,
А как фильтруешь? При каждом нажатии клавиши?
На событие keyUp. Я так понимаю сделать задержку перед фильтрацией коллекции нельзя без rxjs.
Ответить с цитированием
  #6 (permalink)  
Старый 03.01.2017, 14:29
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

Сообщение от Digan Посмотреть сообщение
На событие keyUp. Я так понимаю сделать задержку перед фильтрацией коллекции нельзя без rxjs.
Можно, вот пример на ваниле из underscore

_.debounce = function(func, wait, immediate) {
    var timeout, result;

    var later = function(context, args) {
      timeout = null;
      if (args) result = func.apply(context, args);
    };

    var debounced = restArgs(function(args) {
      if (timeout) clearTimeout(timeout);
      if (immediate) {
        var callNow = !timeout;
        timeout = setTimeout(later, wait);
        if (callNow) result = func.apply(this, args);
      } else {
        timeout = _.delay(later, wait, this, args);
      }

      return result;
    });

    debounced.cancel = function() {
      clearTimeout(timeout);
      timeout = null;
    };

    return debounced;
  };
Ответить с цитированием
  #7 (permalink)  
Старый 03.01.2017, 14:47
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

destus,
зачем нужно в 10 строке проверка и в 24 строке обнуление?
Ответить с цитированием
  #8 (permalink)  
Старый 03.01.2017, 16:52
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

рони,
Цитата:
зачем нужно в 10 строке проверка
Чтобы не запускалось несколько таймеров и отложенного вызова функции func несколько раз. То есть если говорить о keyup, обработчик запустится, если небыло повторного вызова этого типа события и прошло wait ms.
Ответить с цитированием
  #9 (permalink)  
Старый 03.01.2017, 17:31
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

Сообщение от destus
Чтобы не запускалось несколько таймеров
зачем нужно проверять есть ли что-то в timeout? перед тем как остановить таймер, не проще просто остановить без проверок.
Сообщение от destus
if (timeout) clearTimeout(timeout);
и без
Сообщение от destus
timeout = null;
Ответить с цитированием
  #10 (permalink)  
Старый 03.01.2017, 18:11
Аватар для destus
Профессор
Отправить личное сообщение для destus Посмотреть профиль Найти все сообщения от destus
 
Регистрация: 18.05.2011
Сообщений: 1,207

b]рони[/b],
Можно и так. Но в моем случае был копипаст с исходников библиотеки.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ищу Senior Frontend (React, Angular), Москва, 140 - 180 000 gross, full time офис. Ekaterina Polyakova Работа 0 11.08.2016 19:07
как подружить angular и Laravel schel4ok Angular.js 0 19.06.2016 21:23
Angular task workflow mardoksp Angular.js 0 15.02.2016 21:34
Как сделать чтобы angular дожидался ответа Tek Angular.js 0 20.03.2014 16:06
Angular и динамический контент Diem Angular.js 1 26.07.2013 18:57