这实际上比看起来要棘手(挪动一个按钮能有多难,对吧?:))
我简单尝试了一下,发现最整洁的方法是:将编辑器工具栏分配给一个控制器属性,这样你就可以在 outlet 中访问它。
如果你试图重新实现工具栏的行为,就会遇到 @spirobel 提到的那些直接问题,而且随着文本解析逻辑的调整,未来很可能还会遇到其他问题。
基本原则是尽量在最高抽象层级上使用功能,也就是说,我们需要的是实际编辑器(composer editor)的工具栏……那就直接获取它。
例如:
api.modifyClass("component:d-editor", {
@on('didInsertElement')
makeToolbarAccessible() {
if (this.outletArgs && this.outletArgs.editorType === 'composer') {
const controller = getOwner(this).lookup('controller:composer');
controller.set('editorToolbar', this.toolbar);
}
}
});
然后在 outlet 中,我们从 composer 控制器获取工具栏,并向其中添加一个新按钮。也许有一种方法可以利用现有的投票按钮(那将是最理想的),但它被封装在 popupMenu 逻辑中,我没能找到将其分离出来的方法。
setupComponent(attrs, ctx) {
const controller = getOwner(this).lookup('controller:composer');
controller.addObserver('editorToolbar', function() {
if (this._state === 'destroying') return;
const toolbar = controller.editorToolbar;
toolbar.addButton({
group: "extras",
icon: "chart-bar",
title: "poll.ui_builder.title",
sendAction: e => {
controller.send('storeToolbarState', e);
this.send("showPollBuilder");
}
});
const extras = toolbar.groups.find(g => g.group == 'extras');
const pollButton = extras.buttons.find(b => b.icon == "chart-bar");
ctx.set('pb', pollButton);
});
}
然后在模板中:
{{d-button
type="button"
action=pb.action
actionParam=pb
translatedTitle=pb.title
icon=pb.icon
class=pb.className}}
@nexo 试试这个主题组件:discourse-poll-button-bottom.zip (2.5 KB)
附:我刚在 thepavilion.io 上加载了它,看起来能正常工作(仅限移动端)。