If we successfully define a select-kit component within a plugin we are easily able to use it within a *.hbs template file using its pluginApiIdentifiers however, in order to attach that component within a widget using JS code I am not able to make it work. For instance:
And the snippet above will work flawlessly, BUT how I will include that component into a widget like:
api.reopenWidget('user-dropdown', {
html(attrs, state) {
if (this.site.mobileView) {
return h('div.profile-dropdown-container', [
this.attach('header-notifications', attrs),
--> I NEED ATTACH THE COMPONENT HERE <--
]);
}
...
}
});
NOTE: much of the code has been skipped to keep the post brief. Feel free to ask for the full code if needed.
PD: I have already tried to describe this issue at How to attach a component to a widget with just markup? but looks like it was a too complicated explanation so I am trying to reduce the information here to make it clear and try to find an answer.
I think it was a matter of ask myself the right question: “How to render a component within a widget?” that’s why I updated the topic title. I have found few results already such as: How to render Component inside Widget? I will take a look and post any useful finding if it is needed.
Sadly enough looks like it is not possible, simply put we need to find a way to create a widget instead to render what we need to and render a widget within a widget, cause using the connector there are a lot of limitations. Check also: Rendering Component in decorativeWidget API
same issue here.
this is really terrible frontend code that uses widgets and ember components in the same page, it’s really hard to revamp and maintain.
can’t understand what’s the logic
I wasn’t there when widgets were created, but as far as I can tell, it was created for performance reasons at a time where frontend and especially mobile frontend had huge performance issues. And for dev simplicity it was added the possibility to inject components into widgets.
You got to understand that Discourse carries some history and we can’t start from scratch every year.
Ah… it’s very possible that inline-compilation doesn’t (yet) work in theme components. It should work in plugins (as of this week). I’ll see what I can do to add theme component support
Yup, that’s probably the best reference. I don’t think we’ve passed actions ‘for real’ yet in core, so shout if you run into any issues.
Looking at that test again, I suspect the actionForComponentToTrigger() function will need an @bind above it to make sure this works correctly within it.
onChangeUpdateTagSet is invoked for a change, and actionForClick is invoked on button press.
However, I’m struggling with keeping the Tag Chooser populated.
As soon as I introduce my custom action for onChange, the control fails to keep the selected tags up to date in it’s UI (even though my custom variable contains the correct values).
And if I don’t include my custom action for onChange, the components UI works again, but I can’t populate my set.
I tried to add this.scheduleRerender() to the onChangeUpdateTagSet function but this is showing as undefined - clearly not in its scope?
I added a click event to the widget and it does then refresh showing the correct data.
However, it looks like the binding is only going one way so I can’t use the Component to update the external data, only push new data into the Component.
I suspect you’ll need to use widget ‘state’ rather than accessing this.chosen - widget instances are short-lived and ‘stateless’. You’ll get a new instance on each re-render, which means that this.chosen will be reset.