【问题标题】:Angular - Inject/pass service to external libraryAngular - 向外部库注入/传递服务
【发布时间】:2020-03-03 14:10:43
【问题描述】:

我正在开发一个 NPM 包,以便为材料数据表提供额外的功能。其中一个功能是可以传递一个在用户单击特定单元格时将执行的方法。

这里是属性的定义:

内部外部库

click?: (element: any, property: string, event: MouseEvent) => unknown = null;

向它传递一个简单的方法,例如警报或 console.log 可以正常工作:

从使用库的项目中

{
    click: this.alert
}

...

alert(element: any, property: string, mouseEvent: MouseEvent) {
    alert(element[property]);
}

但是,如果我传递一个包含对服务的调用的方法,则库对该服务一无所知,并且该方法会崩溃:

{
    click: this.openDialog
}

...

openDialog(element: any, property: string, mouseEvent: MouseEvent) {
    this.matDialog.open(DialogComponent);
}

ERROR TypeError: Cannot read property 'open' of undefined

如何动态地向外部库提供任何类型的服务?图书馆如何知道使用哪种服务?

或者我走错了方向?我确实尝试过简单地使用事件发射器并将值传递给父组件,但它有局限性(在每个单元格上调用,父级中需要额外的逻辑)

【问题讨论】:

  • 不确定,试试click: this.openDialog.bind(this)。如果你明白我的意思,你的这个可能是错误的
  • 哈哈,是的,我明白你的意思。你的伎俩奏效了,谢谢 :)

标签: angular typescript dependency-injection


【解决方案1】:

这里有两个问题。一,它不知道类型,因为您没有参数化您的click 处理程序(查看Generics)。第二,您正在使用一个普通函数定义,该函数定义隐式绑定正在调用它的上下文。因此,如果您的外部库正在触发 click 并且 this.openDialog 与之相关联,则基本上该库将在其自身内部寻找 this.matDialog.open(DialogComponent);(它不会找到,因此未定义)。

我建议试试这个:

{
    click: this.openDialog.bind(this)
}

...

openDialog(element: any, property: string, mouseEvent: MouseEvent) {
    this.matDialog.open(DialogComponent);
}

【讨论】:

  • 谢谢!第一次看到bind这个语法,很有用
  • @Robouste 是的,JavaScript 中的上下文可能会令人困惑,但要点是:普通函数 = 执行时绑定箭头函数 = 定义时绑定这里还有更多内容,但这应该会有所帮助。跨度>
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-11-21
  • 1970-01-01
  • 1970-01-01
  • 2021-11-13
  • 2014-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多