For those interested I’d like to share the solution which works for me.
get all items on the navigation bar
only trigger click if toggle is visible
ignore dropdown menu items
// app/views/application.js
export default Ember.View.extend({
didInsertElement: function() {
// Bootstrap collapsible navigation bar
$('.nav li a').on('click', function(){
var toggle = $('.navbar-toggle');
// Only click if toggle is visible and ...
if (toggle && toggle.is(':visible') && \
// ... menu item is not a dropdown toggle.
!$(this).hasClass('dropdown-toggle')) {
toggle.trigger("click");
}
});
}});
Just a note on doing jquery stuff, it’s a good idea to cleanup, see clear and destroy events. Also it seems to be best practice to wrap your call back stuff in an Ember.run so it runs in the Ember run loop.
// app/views/application.js
export default Ember.View.extend({
didInsertElement: function() {
// Bootstrap collapsible navigation bar
$('.nav li a').on('click', function(){
Ember.run(function(){
var toggle = $('.navbar-toggle');
// Only click if toggle is visible and ...
if (toggle && toggle.is(':visible') && \
// ... menu item is not a dropdown toggle.
!$(this).hasClass('dropdown-toggle')) {
toggle.trigger("click");
}
});
});
}});
My real world understanding is that it has limited impact unless you’re doing a lot of view changes in the callback in a lot of views. Other people for whom this has fixed real problems feel free to jump in here.
My best practice understanding is based off of this note
Runs the passed target and method inside of a RunLoop, ensuring any
deferred actions including bindings and views updates are flushed at
the end.
Normally you should not need to invoke this method yourself. However
if you are implementing raw event handlers when interfacing with other
libraries or plugins, you should probably wrap all of your code inside
this call.
Ember.run() makes your code testable. Testing disables autorun, and you may get errors when trying to test async code not wrapped in it. See this post I commented on: Setting up testing - #2 by joshpfosi
What is current way to add this code with view being deprecated? I tried on add it to a component of the Navbar. Alternative without using a component?
Tried this addon. There is a flickering issue with the “data-toggle” used in the menu link. The flickering will happen when on desktop version. I finally used the “visible-xs” to fix the flickering and just used attribute binding to allow data-attributes used on the link-to. Here is the code.
I added some extra note avoiding flickering and updated the sample code. That flickering is not Ember related, but this note helps to use the collapse properly:
Note: Don’t forget the .in selector in data-target in the component line, because we would like to close the menu only when it is open. If you miss the .in, the menu in desktop mode would try to collapse which would cause a strange flickering.
/**
* Collapses the navigation menu on mobile/tablet.
*/
navBarClicked(target) {
// Do not collapse on desktop (i.e. if the button navbar toggle is hidden)
if (Ember.$('button.navbar-toggle').is(':hidden')) {
return;
}
// Do not collapse if target is a sub menu
if (Ember.$(target).hasClass('dropdown-toggle')) {
return;
}
Ember.$('.navbar-collapse').collapse('hide');
}