DEV: Add a widget API for injecting services

When declaring your widget you can now add an option like: `services: ['cool']`

And your widget instances will automatically get a `this.cool` property
which will resolve to the service. This saves having to look it up
yourself.
This commit is contained in:
Robin Ward 2021-08-04 13:54:27 -04:00
parent 07c6b720bc
commit 17f28d4018
3 changed files with 26 additions and 6 deletions

View File

@ -335,6 +335,7 @@ export function attachAdditionalPanel(name, toggle, transformAttrs) {
export default createWidget("header", {
tagName: "header.d-header.clearfix",
buildKey: () => `header`,
services: ["router"],
defaultState() {
let states = {
@ -465,9 +466,7 @@ export default createWidget("header", {
params = `?context=${context.type}&context_id=${context.id}&skip_context=${this.state.skipSearchContext}`;
}
const currentPath = this.register
.lookup("service:router")
.get("_router.currentPath");
const currentPath = this.router.get("_router.currentPath");
if (currentPath === "full-page-search") {
scrollTop();
@ -545,9 +544,7 @@ export default createWidget("header", {
state.contextEnabled = false;
const currentPath = this.register
.lookup("service:router")
.get("_router.currentPath");
const currentPath = this.router.get("_router.currentPath");
const blocklist = [/^discovery\.categories/];
const allowlist = [/^topic\./];
const check = function (regex) {

View File

@ -148,6 +148,11 @@ export default class Widget {
this.appEvents = register.lookup("service:app-events");
this.keyValueStore = register.lookup("key-value-store:main");
// We can inject services into widgets by passing a `services` parameter on creation
(this.services || []).forEach((s) => {
this[s] = register.lookup(`service:${s}`);
});
this.init(this.attrs);
// Helps debug widgets

View File

@ -37,6 +37,24 @@ discourseModule("Integration | Component | Widget | base", function (hooks) {
},
});
componentTest("widget services", {
template: hbs`{{mount-widget widget="service-test"}}`,
beforeEach() {
createWidget("service-test", {
tagName: "div.base-url-test",
services: ["router"],
html() {
return this.router.rootURL;
},
});
},
test(assert) {
assert.equal(queryAll(".base-url-test").text(), "/");
},
});
componentTest("hbs template - no tagName", {
template: hbs`{{mount-widget widget="hbs-test" args=args}}`,