1

My jQuery code looks like:

  $("body").on("click", ".nav-bar", function(e){
    $(".my-nav").addClass("open");
  });

I want to angular-ify this. There are a few different controller / views that will have a .nav-bar class, so I'm pretty sure I'll have to use a directive. I'm just not sure how to do that. Ideally, I can strip away all jQuery.

Thanks

Shamoon
  • 41,293
  • 91
  • 306
  • 570

2 Answers2

4

Create a directive:

.directive("navbarAction", function() {
    return {
        restrict: 'A', //<---Look up what this does, there are other options
        link: function(scope, elem, attrs) {
            //Using jQuery
            $(elem).click(function() {
                $(".my-nav").addClass("open");
            });
        }
    }
});

Then in your .nav-bar element, add a navbar-action attribute.

Sample:

<input type='button' value='Click me!' navbar-action />

Angular also comes with jqLite, (you guessed it, a lite version of jQuery), so before importing the entire jQuery lib, see if you can accomplish what you need with jqLite.

tymeJV
  • 103,943
  • 14
  • 161
  • 157
  • I think there's an error in your syntax.. is the function really just an object? – Shamoon Sep 25 '13 at 15:46
  • @Shamoon -- Where at? Sorry, not understanding the question? – tymeJV Sep 25 '13 at 15:48
  • You have `function() { restrict: 'A'....`. If it's a function, how come you're showing as an object? – Shamoon Sep 25 '13 at 15:48
  • @Shamoon -- Ahh, forgot the `return` statement in there. – tymeJV Sep 25 '13 at 15:53
  • To get the same result when not using jquery: `elem.onclick = function(){ $scope.navOpen = true }` and add this to your nav element: `ng-class='{open: navOpen}'`, now the nav element dynamically gets the open class when you click your element. – Pylinux Apr 13 '14 at 15:48
  • @Pylinux -- Good point - you'd probably want to use `ng-click` tho and just set the flag in a controller method. – tymeJV Apr 13 '14 at 17:01
  • @tymeJV -- You are right, the angular way is to control the view with the model. Just frustrating to see everybody adding the entire jQuery library just to use `*.click()`. – Pylinux Apr 26 '14 at 20:34
  • And to anyone reading my previous comment; when you are using angular it is better to use bind, e.g. `elem.bind('click', function(){})` and not `onclick` as my previous comment states. – Pylinux Apr 26 '14 at 20:43
1

In angular, you usually don't add classes based on action, but rather based on the status of your app. For example, if you were select one of many items in a list, you could change it's selected attribute to "true".

For example:

$scope.items = [{id: 1, name: "test", selected: false}, {id: 2, name: "test 2", selected: true}, {id: 3, name: "test 3", selected: false}]

Then in your template, you will use ng-class to let angular handle changing classes:

<ul>
  <li ng-repeat="item in items" ng-class="{ selected: item.selected }">{{item.name}}</li>
</ul>

In the case of your navbar, I would actually think about your app state. Is this navbar reflective of your current location in the app? If that's the case, you should start checking your $routeParams (or $stateParams if you use the excellent ui-router) and conditionally adding classes that way.

The point here is that angular-fying an app is more than porting jQuery actions; it's about building a smarter app.

Mike Robinson
  • 24,971
  • 8
  • 61
  • 83
  • ...just noticed angular-frying, and I think I'm going to keep it. Angular-fry: when you break a site by converting to angular without understanding it's conventions. – Mike Robinson Sep 25 '13 at 15:46