基于类的扩展
如果您的扩展要监听多个事件并跟踪状态,您可能希望将您的扩展定义为一个JavaScript类。类是创建对象的模板。它封装了数据和操作该数据的方法。这种封装有助于保持您的扩展更有组织性。挑战在于如何以一种可以用作Antora扩展的方式定义类。本页将向您展示如何做到这一点。
扩展类结构
基于类的扩展的基本结构如下:
-
定义一个以您的扩展命名的类(例如,MyExtension)
-
添加一个静态的register方法,Antora可以调用
-
将监听器定义为实例方法(例如,
onPlaybookBuilt ({ playbook })
) -
添加一个接受生成器上下文并从类中注册监听器的构造函数
-
导出类定义
这是我们扩展类的框架:
class MyExtension {
}
让我们填写细节。
register方法和实例化
Antora不会创建您的类的实例,但您可以使用类上的静态register方法来实现。如果您熟悉Java,您可以将其视为类的主方法。以下是入口点的外观:
class MyExtension {
static register () {
new MyExtension(this)
}
}
module.exports = MyExtension
Antora将只看到导出类定义上的register方法,并调用它以启动进程。其余的工作发生在扩展实例中。
请注意,静态register方法将我们从静态函数转变为扩展类的实例。register方法将生成器上下文传递给扩展类的构造函数,以便它可以访问并存储对其的引用。
监听器方法
监听器被定义为扩展类上的方法。它们将像任何其他监听器函数一样被调用,只是它们将同时引用类的当前实例(this
)和生成器上下文(this.context
)。这样,它们可以访问扩展的属性(扩展状态)和生成器中的上下文变量。以下是再次定义监听器为方法的扩展类:
class MyExtension {
static register () {
new MyExtension(this)
}
onPlaybookBuilt () {
this.startTime = +new Date
}
onSitePublished () {
const elapsed = (+new Date - this.startTime) / 1000
const logger = this.context.getLogger('my-extension')
logger.info(`elapsed time: ${elapsed}s`)
}
}
module.exports = MyExtension
现在只剩下将这些监听器与事件连接起来。
构造函数和添加监听器
下一步是创建一个接受生成器上下文并添加监听器的构造函数。以下是再次定义带有构造函数的扩展类:
class MyExtension {
static register () {
new MyExtension(this)
}
constructor (generatorContext) {
;(this.context = generatorContext)
.on('playbookBuilt', this.onPlaybookBuilt.bind(this))
.on('sitePublished', this.onSitePublished.bind(this))
}
onPlaybookBuilt () {
this.startTime = +new Date
}
onSitePublished () {
const elapsed = (+new Date - this.startTime) / 1000
const logger = this.context.getLogger('my-extension')
logger.info(`elapsed time: ${elapsed}s`)
}
}
module.exports = MyExtension
在添加每个监听器时,必须将其绑定到扩展实例(即this
)。否则,监听器将无法访问扩展实例上的属性。监听器仍然可以使用context
属性访问生成器上下文,构造函数将生成器上下文分配给该属性。
正如您所见,使用基于类的扩展可以使您的扩展代码更有组织性。它还允许您的扩展利用其他面向对象的模式,如继承、组合和委托。