Директива атрибута Angular - ошибка при сборке продукта ожидала 1 аргумент, но получила 0

Я работаю над большим приложением, разрабатываемым несколькими командами в течение определенного периода времени.

Разработчик внешнего интерфейса из другого места добавил много повторяющегося императивного кода с манипулированием dom с использованием jquery повсюду в приложении (в каждом компоненте) для решения проблем доступности.

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

Вот моя директива.

import { Directive, HostListener, ElementRef, OnInit, Input, AfterViewInit } from '@angular/core';
import { AccessibilityService } from 'src/app/services/accessibility.service';

@Directive({
  selector: '[keyboardFocus]'
})
export class KeyboardFocusDirective implements OnInit, AfterViewInit {

  @Input('outlineOnFocusFor') outlineFor: 'self'|'parent'|'none'|null|undefined;

  private readonly outlineStyleOnFocus = '1px solid black';
  private tabindexChange: boolean;
  private elemToOutine: any;

  constructor(private el: ElementRef, private accessibilityService: AccessibilityService) { }

  ngOnInit() {
    this.accessibilityService.currentTabindexChange.subscribe((tabindexChange: boolean) => {
      this.tabindexChange = tabindexChange;

      if (this.el && this.el.nativeElement) {
        this.el.nativeElement.tabIndex = this.tabindexChange ? -1 : 0;
      }
    });
  }

  ngAfterViewInit() {
    switch (this.outlineFor) {
      case 'parent':
        this.elemToOutine = this.el.nativeElement.parentElement;
        break;
      case 'none':
        this.elemToOutine = null;
        break;
      case 'self':
      case null:
      case undefined:
      default:
        this.elemToOutine = this.el.nativeElement;
        break;
    }
  }

  @HostListener('keyup.tab', ['$event']) 
  @HostListener('keyup.shift.tab') 
  onKeyboardTabFocus(event: KeyboardEvent) {
    if (!this.elemToOutine)
      return;

    this.elemToOutine.style.outline = this.outlineStyleOnFocus;
    event.stopImmediatePropagation();
  }

  @HostListener('blur', ['$event'])
  onKeyboardBlur(event: KeyboardEvent) {    
    if (!this.elemToOutine)
      return;

    this.elemToOutine.style.outline = '';
    event.stopImmediatePropagation();
  }
}

Вот как я использую его в воображаемом компоненте.

<div class="something">
  <section class="something-else" keyboardFocus outlineOnFocusFor="parent">some content 1</section>
  <section class="something-else-2" keyboardFocus>some content 2</section>
  <section class="something-else-3" keyboardFocus outlineOnFocusFor="none">some content 3</section>
</div>

Кажется, это отлично работает в сборке dev. Однако сборка CLI с флагом --prod выдает такую ​​ошибку:

ОШИБКА в src/app/features/enrollments/ate-requests/ate-requests.component.html(73,17): Директива KeyboardFocusDirective, ожидалось 1 аргумент, но получено 0. src/app/ features/enrollments/ate-requests/ate-requests.component.html(141,17): : Директива KeyboardFocusDirective, ожидалось 1 аргумент, но получено 0. src/app/features/enrollments/ate- request/ate-requests.component.html(156,23): : Директива KeyboardFocusDirective, ожидалось 1 аргумент, но получено 0.

Одна и та же ошибка, везде где используется директива. Я не мог понять, что может быть недостающим аргументом. Мы ценим любые предложения. Спасибо :)


person Ren    schedule 06.07.2020    source источник


Ответы (3)


Для начала (не знаю, будет ли этого достаточно), outlineOnFocusFor — это ввод. Поэтому квадратные скобки:

  <section class="something-else" keyboardFocus [outlineOnFocusFor]="parent">some content 1</section>
person mbojko    schedule 06.07.2020
comment
Я хочу назначить строковый литерал «родительский» для layoutOnFocusFor, а не какой-либо элемент (с именем «родительский» или «я») родительского компонента. Тем не менее, я попробовал ваше решение @mbojko. Мне пришлось сделать [outlineOnFocusFor]='parent'. Никакой разницы не было :( - person Ren; 06.07.2020
comment
Использование [outlineOnFocusFor]="parent" передает переменную-член parent, тогда как outlineOnFocusFor="parent" передает строковый литерал 'parent'. - person Michael D; 06.07.2020

Вам нужно удалить аргумент $event из hostListeners. После удаления аргумента он должен работать нормально.

Пожалуйста, найдите обновленный код ниже. Возможно, это решит проблему, с которой вы столкнулись.

import { Directive, HostListener, ElementRef, OnInit, Input, AfterViewInit } from '@angular/core';
import { AccessibilityService } from 'src/app/services/accessibility.service';

@Directive({
  selector: '[keyboardFocus]'
})
export class KeyboardFocusDirective implements OnInit, AfterViewInit {

  @Input('outlineOnFocusFor') outlineFor: 'self'|'parent'|'none'|null|undefined;

  private readonly outlineStyleOnFocus = '1px solid black';
  private tabindexChange: boolean;
  private elemToOutine: any;

  constructor(private el: ElementRef, private accessibilityService: AccessibilityService) { }

  ngOnInit() {
    this.accessibilityService.currentTabindexChange.subscribe((tabindexChange: boolean) => {
      this.tabindexChange = tabindexChange;

      if (this.el && this.el.nativeElement) {
        this.el.nativeElement.tabIndex = this.tabindexChange ? -1 : 0;
      }
    });
  }

  ngAfterViewInit() {
    switch (this.outlineFor) {
      case 'parent':
        this.elemToOutine = this.el.nativeElement.parentElement;
        break;
      case 'none':
        this.elemToOutine = null;
        break;
      case 'self':
      case null:
      case undefined:
      default:
        this.elemToOutine = this.el.nativeElement;
        break;
    }
  }

  @HostListener('keyup.tab') 
  @HostListener('keyup.shift.tab') 
  onKeyboardTabFocus(event: KeyboardEvent) {
    if (!this.elemToOutine)
      return;

    this.elemToOutine.style.outline = this.outlineStyleOnFocus;
    event.stopImmediatePropagation();
  }

  @HostListener('blur')
  onKeyboardBlur(event: KeyboardEvent) {    
    if (!this.elemToOutine)
      return;

    this.elemToOutine.style.outline = '';
    event.stopImmediatePropagation();
  }
}
person Minal Shah    schedule 06.07.2020
comment
Спасибо за быстрый ответ. Это не помогло. Если свойство layoutOnFocusFor не указано, оно будет неопределенным или пустым для этого экземпляра директивы, и это допустимое значение для «outlineFor». - person Ren; 06.07.2020
comment
Эй, я обновил ответ выше. Пожалуйста, попробуйте это один раз. - person Minal Shah; 06.07.2020
comment
Привет, Минал Шах, спасибо. Если я удалю ['$event'] из декоратора @HostListener, событие аргумента будет иметь значение undefined в методах onKeyboardTabFocus и onKeyboardBlur. event.stopPropagation() вызовет исключение времени выполнения. Тем не менее, попробую, а там посмотрим. На данный момент, я в порядке, чтобы попробовать что-нибудь :) - person Ren; 06.07.2020
comment
Просто к вашему сведению, если вы не прочитали мой вопрос полностью, мой исходный код отлично работает, когда я выполняю ng serve.. или ng build. Он выдает ошибки, когда я делаю ng build --prod - person Ren; 06.07.2020
comment
Обновление: сделал то, что вы предложили, это не помогло (как я уже ожидал). В любом случае, большое вам спасибо. - person Ren; 06.07.2020

Нашел. Так чертовски глупо .. Спасибо всем за ваше время и предложения :о)

Отсутствует аргумент $event в декораторе

@HostListener('keyup.shift.tab'). 

Так должно быть

@HostListener('keyup.shift.tab', ['$event'])
person Ren    schedule 06.07.2020