Exploring EmberJS and in the process of transitioning an existing website to this framework, I encountered a challenge with a Bootstrap-based dropdown. While troubleshooting this issue, I found that it deepened my understanding of Ember's concepts, although I am left with some lingering questions.
To implement the dropdown (alongside other elements), I utilized the ember-bootstrap module. Below is the code snippet for the dropdown functionality:
{{#bs-dropdown as |dd|}}
{{#dd.button}}
Sort by
{{/dd.button}}
{{#dd.menu as |ddm|}}
{{#ddm.item}}{{#ddm.link-to "index"}}Price low to high{{/ddm.link-to}}{{/ddm.item}}
{{#ddm.item}}{{#ddm.link-to "index"}}Price high to low{{/ddm.link-to}}{{/ddm.item}}
{{/dd.menu}}
{{/bs-dropdown}}
I now wish to trigger specific JavaScript code when a user clicks on one of the dropdown items. Referring to the module's documentation, I located and modified the code within the menu item component as shown below:
export default Component.extend({
layout,
classNameBindings: ['containerClass'],
/* ... */
actions: {
// My addition
sortByPrice(param){
alert("sorting");
},
// End of the addition
toggleDropdown() {
if (this.get('isOpen')) {
this.send('closeDropdown');
} else {
this.send('openDropdown');
}
},
},
});
Subsequently, I made updates to the hbs file as follows:
{{#dd.menu as |ddm|}}
{{#ddm.item action "sortByPrice" low_to_high}}
{{#ddm.link-to "index" action "sortByPrice" low_to_high}}
Prix croissant
{{/ddm.link-to}}
{{/ddm.item}}
{{/dd.menu}}
However, despite these changes, the desired outcome was not achieved. This led me to include the *action* attribute to the *link-to* element and define the corresponding action in its component file as well.
import LinkComponent from '@ember/routing/link-component';
export default LinkComponent.extend({
actions: {
sortByPrice(param){
alert("sorting");
console.log("sorting");
},
},
});
Upon further investigation, I realized that the *link-to* component extending the LinkComponent does not inherently handle click events, as elaborated in this thread.
Feeling somewhat frustrated, I resorted to a less elegant workaround that served the purpose:
{{#bs-dropdown id="sort" as |dd|}}
{{#dd.button}}
Sort by
{{/dd.button}}
{{#dd.menu as |ddm|}}
{{#ddm.item action "sortByPrice" low_to_high}}
<a
class="dropdown-item"
onclick="sortByPrice('low_to_high'); return false;"
href="#"
>
Price low to high
</a>
{{/ddm.item}}
{{/dd.menu}}
{{/bs-dropdown}}
Here are my inquiries:
- Why did defining actions in both the Component file and the hbs file not yield the expected result?
- Why doesn't the LinkComponent intrinsically manage click events? While links traditionally redirect users to a new page, DOM events are still triggered. Does Ember purposely overlook this behavior to prevent developers from handling it? Understanding the rationale behind this decision would be beneficial.
- Is there a more optimal solution than the one I've implemented?
Thank you.