【问题标题】:Angular attribute directive - error on prod build expected 1 arguments but got 0Angular 属性指令 - prod 构建错误,预期 1 个参数但得到 0
【发布时间】:2020-10-26 11:37:26
【问题描述】:

我正在开发一个由多个团队在一段时间内开发的大型应用程序。

一位来自不同地点的前端开发人员添加了大量重复的命令式代码,并在应用程序中的任何地方(在每个组件中)使用 jquery 进行 dom 操作,以解决可访问性问题。

我正在尝试清理该代码。我将一些代码移到了指令中(例如:- 当元素被键盘聚焦时勾勒出轮廓,或者在模糊时移除轮廓)

这是我的指令。

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>

这似乎在开发版本中运行良好。但是使用 --prod 标志构建的 CLI 会出现如下错误:

src/app/features/enrollments/ate-requests/ate-requests.component.html(73,17) 中的错误:: Directive KeyboardFocusDirective,需要 1 个参数,但得到 0。 src/app/features/enrollments/ate-requests/ate-requests.component.html(141,17): : Directive KeyboardFocusDirective,需要 1 个参数,但得到 0。 src/app/features/enrollments/ate-requests/ate-requests.component.html(156,23): : Directive KeyboardFocusDirective,需要 1 个参数,但得到 0。

使用该指令的所有地方都出现同样的错误。我无法弄清楚缺少的论点可能是什么。任何建议,将不胜感激。谢谢你:)

【问题讨论】:

    标签: angular angular-cli angular-directive ng-build


    【解决方案1】:

    找到了。太傻了..感谢大家的时间和建议:o)

    装饰器中缺少的参数 $event

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

    应该是

    @HostListener('keyup.shift.tab', ['$event'])
    

    【讨论】:

      【解决方案2】:

      您需要从 hostListeners 中删除 $event 参数。删除参数后,它应该可以正常工作。

      请在下面找到更新后的代码。也许这会解决您面临的问题。

      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();
        }
      }
      

      【讨论】:

      • 感谢您的快速回复。那没有帮助。如果未提供 outlineOnFocusFor,则该指令实例将是 undefined 或 null,并且它是 'outlineFor' 的可接受值。
      • 嘿,我已经更新了上面的答案。请尝试一次。
      • 您好 Minal Shah,谢谢。如果我从 @HostListener 装饰器中删除 ['$event'],则参数事件将在方法 onKeyboardTabFocus 和 onKeyboardBlur 中具有未定义的值。 event.stopPropagation() 将抛出运行时异常。尽管如此,我还是会尝试一下,看看。在这一点上,我可以尝试任何事情:)
      • 仅供参考,如果您没有完全阅读我的问题,当我执行“ng serve”或“ng build”时,我的原始代码可以正常工作。当我执行“ng build --prod”时会引发错误
      • 更新:按照你的建议做了,但没有帮助,(正如我已经预料到的那样).. 非常感谢你..
      【解决方案3】:

      对于初学者(我不知道这是否足够),outlineOnFocusFor 是一个输入。因此,方括号:

        <section class="something-else" keyboardFocus [outlineOnFocusFor]="parent">some content 1</section>
      

      【讨论】:

      • 我想为outlineOnFocusFor分配一个字符串文字'parent',而不是父组件的任何成员(名称为'parent'或'self')。不过,我尝试了您的解决方案@mbojko。我必须做 [outlineOnFocusFor]="'parent'"。没有任何区别:(
      • 使用[outlineOnFocusFor]="parent"传递成员变量parent,而outlineOnFocusFor="parent"传递字符串文字'parent'
      猜你喜欢
      • 2021-07-29
      • 2021-08-22
      • 2019-08-28
      • 2019-08-02
      • 2018-09-19
      • 1970-01-01
      • 2018-08-02
      • 2021-03-03
      • 2020-10-23
      相关资源
      最近更新 更多