const myModule = self.apos.modules['my-module']
,如果我在apostrophe-pages
的构造中使用它,其中my-module
是apostrophe-module
的子类,则foo
将是{{ 1}}?
答案 0 :(得分:2)
是的,因为模块是以特定顺序实例化的。标准模块的顺序在npm模块的defaults.js
中的apostrophe
中。之后,将按照app.js
中找到的顺序实例化模块。
作为最佳实践,您不应在construct
中“执行操作”,而只能分配随后从afterConstruct
或更高版本调用的方法。但是,在这种情况下,必须稍后,因为那些其他模块仍不会被实例化。
您可以安全地依靠modulesReady
方法中存在的所有其他模块。最后一个模块实例化后,将在所有模块中调用此方法:
module.exports = {
construct: function(self, options) {
self.modulesReady = function(callback) {
self.apos.modules['my-module'] ... do something ...
return callback(null);
};
}
}
但是,您正在项目级别扩展apostrophe-pages
。并且apostrophe-pages
已经具有modulesReady
方法。您可以使用super
模式来确保仍被调用。但是有一种更简单的方法。
从Apostrophe 2.63.0开始,您可以使用promise事件:
module.exports = {
construct: function(self, options) {
self.on('apostrophe:modulesReady', 'getTheMonkeys', function() {
const req = self.apos.tasks.getAnonReq();
return self.apos.modules['monkeys'].find(req).toArray().then(function(monkeys) {
console.log(monkeys);
});
});
}
}
getTheMonkeys
参数为此模块方便地定义了一个getTheMonkeys
方法,以防您想在扩展该模块的模块中有意覆盖其行为。如果那似乎还不重要,请记住,您必须为事件处理程序指定一个描述性名称inCamelCase,以说明其具体功能。
请注意,modulesReady
中的代码在站点启动时仅运行一次。这就是construct
中代码的作用,因此它是所问问题的正确答案。但是对于那些想要在每次页面加载时都要做一些事情的人,而不仅仅是在启动时,正确的代码将是:
module.exports = {
construct: function(self, options) {
self.on('apostrophe-pages:serve', 'getTheMonkeys', function(req) {
return self.apos.modules['monkeys'].find(req).toArray().then(function() {
// Got all the monkeys on every page load.
// Now you can access them as `data.monkeys` in your page templates.
req.data.monkeys = monkeys;
});
});
}
}
请注意,这里我们有一个真实的req
,因此我们可以将数据附加到req.data
并使其可用于页面模板。而且,每次猴子列表都是最新的。
如果您使用的是节点8或更高版本,则可以使用async / await,这更加简洁:
module.exports = {
construct: function(self, options) {
self.on('apostrophe-pages:serve', 'getTheMonkeys', async function(req) {
req.data.monkeys = await self.apos.modules['monkeys'].find(req).toArray()
});
}
}