Подтвердить что ты не робот

В Angular2, как узнать, когда потерянное фокусное поле ANY формы

В Angular2 как узнать, когда ЛЮБОЕ поле ввода потеряло фокус..! Если я использую наблюдаемые в форме:

form.valueChange.subscribe...

не работает, так как я действительно хочу знать, когда поле потеряло размытие (фокус), поэтому я могу обновить свой магазин (если я обновляю хранилище до потери фокуса, мой курсор на текстовый ввод перемещается в конец, так как данные обмениваются, что странно выглядит)

конечно, я могу добавить (change)="" на каждый вход, но у меня есть много...

Я думал о чем-то вроде:

this.form.valueChanges.debounceTime(1000).subscribe((changes:any) => {
  if (this.form.dirty){
    this.appStore.dispatch(this.resellerAction.updateResellerInfo(changes))
  }
});

но проблема в том, что грязный остается грязным, поэтому он застрял в вечной петле изменений изменений...

ТХ

Шон

4b9b3361

Ответ 1

Событие blur не пузырится, поэтому нам нужно прослушивать каждый элемент ввода напрямую. Angular обеспечивает хорошее решение для этой ситуации.

Директива, которая применяется ко всем входным элементам внутри вашего шаблона.

В этой директиве используется хост-слушатель для прослушивания событий blur для всех элементов, в которых применяется селектор, и пересылает событие bbbling input-blur:

@Directive({
  selector: 'input,select',
  host: {'(blur)': 'onBlur($event)'}
})
class BlurForwarder {
  constructor(private elRef:ElementRef, private renderer:Renderer) {}

  onBlur($event) {
    this.renderer.invokeElementMethod(this.elRef.nativeElement, 
        'dispatchEvent', 
        [new CustomEvent('input-blur', { bubbles: true })]);
    // or just 
    // el.dispatchEvent(new CustomEvent('input-blur', { bubbles: true }));
    // if you don't care about webworker compatibility
  }
}

Добавив директиву BlurForwarder в directives: [...], она будет применяться ко всем элементам в своем шаблоне, которые соответствуют селектору.
Хост-слушатель прослушивает пузырьки input-blur событий и вызывает наш обработчик событий:

@Component({
  selector: 'my-component',
  directives: [BlurForwarder],
  host: {'(input-blur)':'onInputBlur($event)'},
  template: `
<form>
  <input type="text" [(ngModel)]="xxx">
  <input type="text" [(ngModel)]="yyy">
  <input type="text" [(ngModel)]="zzz">
</form>`
}) {
  onInputBlur(event) {
    doSomething();
  }
}

Ответ 2

Почему бы не использовать focusout, он пузырится по умолчанию в DOM

Здесь простая директива, которая ловит фокус и проверяет, является ли входное значение пустым, а затем устанавливает значение в ноль:

@Directive({
  selector: '[blankToZero]'
})
export class BlankToZeroDirective {
  constructor(private elementHost: ElementRef) { }

  @HostListener('focusout')
  ensureInput(): void {
    if (Util.isNullOrEmpty(this.elementHost.nativeElement.value)) {
      this.elementHost.nativeElement.value = 0;
    }
  }
}