编辑:已重新归类为错误。
完整的重现步骤如下。
我正在主题组件中使用 api.modifyClass。
在大多数页面上,这都可以正常工作,但在某些主题中,当页面重新加载时,该属性未添加到用户模型中。我找不到为什么它在大多数主题中有效,但在某些主题中无效,或者那些无效的主题有什么共同点。
有人明白我在这里做错了什么吗?
简而言之,在 modifyClass 下方添加 api.container.lookup 来查找模型,可以解决此问题。
编辑:已重新归类为错误。
完整的重现步骤如下。
我正在主题组件中使用 api.modifyClass。
在大多数页面上,这都可以正常工作,但在某些主题中,当页面重新加载时,该属性未添加到用户模型中。我找不到为什么它在大多数主题中有效,但在某些主题中无效,或者那些无效的主题有什么共同点。
有人明白我在这里做错了什么吗?
简而言之,在 modifyClass 下方添加 api.container.lookup 来查找模型,可以解决此问题。
我的天哪。我可能知道!
我认为你需要添加一个 pluginId
<script type="text/discourse-plugin" version="0.1">
api.modifyClass('model:user', {
pluginId: 'my-plugin',
testProperty: function() {
return 1;
}
});
</script>
它在较新版本中是必需的,我昨天为几个主题提交了 PR 来添加这个。我可能终于要成为一名插件/主题开发者了。
谢谢 Jay!这确实对我的测试实例产生了影响。
但不幸的是,这并非万能的解决方案,问题依然存在 ![]()
是的,我认为 pluginId 的存在是为了防止修改被应用两次。缺少它不应该解释为什么它一次都没有运行?
糟糕。正当我以为自己懂了点什么的时候。![]()
我曾想,如果有什么东西在修改类,那可能是竞争条件,看哪个先完成。但 JavaScript 对我来说仍然是个谜。
这仍然是代码中的一个问题,所以提出来是合理的。
是的,我也有这个想法。但它仍然在一个测试站点上失败,而这个站点只有这个主题组件。
有趣的是,如果将其添加到主题组件中,例如:
/javascripts/discourse/initializers/test-init.js.es6这样,行为是否会改变/改善?
我不确定这些东西在语义上是否完全相同……
……理论上,两者都应该在浏览器刷新时进行评估,之后,由于修改应该已经应用,因此在路由转换时竞态条件应该无关紧要……
不,行为相同。
我创建了一个主题组件,其中包含 javascripts/discourse-test/initializers/initialize-discourse-test.js.es6:
import { withPluginApi } from "discourse/lib/plugin-api";
export default {
name: 'discourse-test-initializer',
initialize(){
console.log('here1');
withPluginApi("0.1", api => {
console.log('here2');
api.modifyClass('model:user', {
pluginId: 'test',
testFunction: function() {
console.log('here3');
return 2;
}
});
});
}
}
在每一页上打印
here1
here2
在某些主题中,在控制台中输入 Discourse.currentUser.testFunction() 可以工作,并产生 here3 和 2 作为输出。
在某些主题中,它不起作用(Uncaught TypeError: Discourse.currentUser.testFunction is not a function)
好的,我看到了一个来自一篇似乎已被移除的有用帖子的通知。
该建议不起作用,但它包含了一个帮助我解决此问题的线索。
在不起作用的代码下方添加以下代码片段可以持续解决我遇到的问题。我在多个独立论坛上都进行了测试,包括 stable 和 tests-passed。我认为这应该被重新归类为 Bug…
<script type="text/discourse-plugin" version="0.1">
const userModel = api.container.lookup("model:user");
</script>
@Johani 感谢您的帮助!
将此重新归类为 bug。
我在插件 API 代码 app/assets/javascripts/discourse/app/lib/plugin-api.js 中添加了一个 console.log,以便在调用 modifyClass 时进行记录。
我已移除所有外部插件,以确保没有冲突。
重现步骤:
在 stable 上创建一个空的论坛(没有 Ember CLI)。在 tests-passed(没有 Ember CLI)上此功能也不起作用。我没有用 Ember CLI 测试过。
添加一个主题组件,并在 Common - Head 中添加以下内容:
<script type="text/discourse-plugin" version="0.1">
api.modifyClass('model:user', {
pluginId: 'test-tc',
testFunction: function() {
return 1;
}
});
</script>
加载主页
控制台显示 modifyClass called for model:user _application-08d9058ddd37ba80992f770509f4919ad0738a17f14fb85167b1dc1f32f8b56e.js:23490:16 Object { pluginId: "test-tc", testFunction: testFunction() }
在控制台中输入 Discourse.currentUser.testFunction()
打印出 “1”
Discourse.currentUser.testFunction()Uncaught TypeError: Discourse.currentUser.testFunction is not a function<script type="text/discourse-plugin" version="0.1">
const userModel = api.container.lookup("model:user");
api.modifyClass('model:user', {
pluginId: 'test-tc',
testFunction: function() {
return 1;
}
});
</script>
“model:user” was already cached in the container. Changes won't be applied.Discourse.currentUser.testFunction()Uncaught TypeError: Discourse.currentUser.testFunction is not a function<script type="text/discourse-plugin" version="0.1">
api.modifyClass('model:user', {
pluginId: 'test-tc',
testFunction: function() {
return 1;
}
});
const userModel = api.container.lookup("model:user");
</script>
Discourse.currentUser.testFunction()重新审视这个问题:
在 Discourse 2.8 及更高版本中,使用 Discourse.User.current().testFunction() ,情况 #2 仍然失败。
我也遇到了 modifyClass 的问题,不确定是否相关? Issues overriding getters in a controller (3.0.0)
我已经改进了我们针对这种情况的警告:
我还编写了这份文档,其中解释了原因以及如何解决它:
我认为这应该能解决此主题中的所有顾虑。如果不能,请分享一些失败的代码示例,我会看看。
此主题已在 3 天后自动关闭。不再允许回复。