【问题标题】:Check if output is present on component检查组件上是否存在输出
【发布时间】:2020-06-07 02:07:19
【问题描述】:

考虑以下组件:

@Component({
  selector: 'app-test'
  template: 'Hello!'
}}
export class TestComponent {
  @Output() readonly selectionChange = new EventEmitter<SomeTypeHere>();
}

随叫随到:

<app-test (selectedChange)="selectedChangeHandler($event)"></app-test>

请注意,我写的是selectedChange,而不是正确的输出名称selectionChange。启用了 strictTemplates 标志的 Angular 9 对我一点帮助都没有。它默默地失败了。有趣的是,如果我对@Input 做同样的事情,应用程序会捕获错误并且不会编译。

如果我尝试“监听”一个不存在的@Output,有什么方法可以抛出错误?

【问题讨论】:

  • 以前版本的 Angular 是否有任何错误?我认为它从来没有对此抛出任何错误
  • @Aravind 不,它从不抛出错误。我在问有没有可能。提前致谢。
  • 为什么要抛出错误?有特殊需要吗?我正在尝试理解您的问题
  • @Aravind 好吧,我正在与许多开发人员一起开发企业应用程序,因此拥有某种信息/警告/错误很重要。有时有人更改/删除共享库中的@Output(),甚至在应用程序上忘记删除 calls... 因为我们没有编译错误,就像我们有 @ 987654329@,我们无法找到导致某些问题的确切原因(甚至无法在代码中保留垃圾)。单元测试会有所帮助吗?也许吧,但由于时间关系,当时还不可能。

标签: angular angular-directive angular9


【解决方案1】:

没有抛出错误,因为Angular中的event binding不仅与@Outputs和EventEmitters一起使用,还用于监听DOM eventsclickkeyup等. 它甚至可以用来收听custom events。例如,如果您在子组件中创建并发出自定义事件:

constructor (private el: ElementRef) {}
ngOnInit(): void {
    const domEvent = new CustomEvent('selectedChange', { custom: true });
    this.el.nativeElement.dispatchEvent(domEvent);
}

然后在父组件中你可以通过它的名字来捕捉它:

<app-test (selectedChange)="selectedChangeHandler($event)"></app-test>

Angular 在内部使用target.addEventListener(type, listener [, options]);(您可以通过查看下面的链接确定它),其中type 可以是任何字符串。

这就是为什么它在找不到匹配的@Outputs 时不会抛出任何异常。

listenToElementOutputs

DefaultDomRenderer2.listen

EventManager.addEventListener

DomEventsPlugin.addEventListener

【讨论】:

  • 嘿@Kirill Simonov 感谢您的回答!好吧,接受您的陈述:“没有抛出错误,因为 Angular 中的事件绑定不仅与 @Outputs 和 EventEmitters 一起使用,而且还用于侦听诸如 click、keyup 等 DOM 事件”,为什么如果您通过不存在的@Input()(请记住,输入具有相同的特征:可以是全局的,例如disabledid 等)Angular 抛出错误?为什么它适用于@Input,但不适用于@Output?另外,如果传递了不存在的@Output,我正在尝试找到一种警告/抛出错误的方法。
  • @dev_054 这是因为属性集受限于 DOM 元素、指令或组件的现有属性,因此 Angular 可以轻松检查该属性是否存在。另一方面,事件是使用addEventListener 绑定的(我将在我的答案中添加一些链接以显示它)。我认为,这是有意完成的,因此开发人员可以将事件绑定与他们自己的自定义事件一起使用。我相信没有办法在编译时禁用这种行为。尽管某些 IDE(如 IntelliJ Idea)可能会突出显示这些地方并显示警告。
  • @dev_054 请记住,您还可以使用[attr.any-attribute]HTML attributes 使用单向绑定,在这种情况下也不会抛出错误。
【解决方案2】:

您的问题没有直接的解决方案,但是可以涵盖某些情况。

  1. 如果您有任何输出在 100% 的地方使用,例如按钮 click 事件,那么您可以将其作为选择器的一部分,即 selector: 'app-test[selectionChange]'。您也可以这样做,例如:selector: 'app-test[selectionChange]', app-test[click]' 表示 clickselectionChange 是必需的。
  2. 如果您正在重构代码并将输出重命名,即 selectionChangeselectedChange,那么您可以使用此选择器:selector: 'app-test:not([selectionChange])' 强制用户更新。

【讨论】:

    【解决方案3】:

    这应该适合你。

    ngOnInit() : void {
     if(this.selectionChange.observers.length > 0){
       console.log("Nice coding");
     }else{
      console.log("Something is wrong!!");
    }
    

    【讨论】:

      【解决方案4】:

      如果你使用 VS Code,你可以安装这个扩展:Angular Language Service 将在未定义方法或属性时抛出警告。此扩展适用于输出和输入(以及 attrs 等)。

      【讨论】:

      • 您的示例显示了一个@Input。对于@Output,Angular 语言服务无济于事。如果您需要我澄清问题,请告诉我。
      • 对于@Output,您将看到相同的错误消息。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-26
      • 2021-12-22
      • 1970-01-01
      • 2019-04-12
      • 1970-01-01
      相关资源
      最近更新 更多