I have created this little dropdown directive in Angular. The idea is that you create a nav element with a ul inside. The directive prepends a chevron and toggles scope.visible
when you click it. Two functions watch scope.visible
, the first folds the dropdown, and the second reverses the chevron.
I'm attacking this from a jQuery perspective so I suspect I'm not doing this in the optimal way. How can I improve this code to make it more testable, more readable, and more Angular?
Is it good to create all these little helper methods, or should I be splitting my code out into smaller pieces?
myApp.directive('dropdown', function () {
return {
scope: true,
link: function (scope, element) {
var menu = element.find('ul');
var body = angular.element('body');
var unfold = angular.element("<a href='#'><i/></a>");
var toggleVisible = function () {
scope.menu.visible = !scope.menu.visible;
scope.$apply();
};
var unsetVisible = function () {
scope.menu.visible = false;
scope.$apply();
};
var showMenu = function () {
if (scope.menu.visible) {
menu.show();
} else {
menu.hide();
}
};
var toggleChevron = function () {
var c;
if (scope.menu.visible) {
c = 'fa-caret-up';
} else {
c = 'fa-caret-down';
}
unfold.find('i').attr('class', c);
};
var escapeKey = function (e) {
if (e.which === 27) {
unsetVisible();
}
};
var chevronClick = function (e) {
toggleVisible();
e.stopPropagation();
};
element.prepend(unfold);
scope.menu = {visible: false};
unfold.on('click', chevronClick);
body.on('click', unsetVisible);
body.on('keyup', escapeKey);
scope.$watch('menu.visible', showMenu);
scope.$watch('menu.visible', toggleChevron);
}
};
});