Arnaud Denoyelle Arnaud Denoyelle - 6 months ago 20
AngularJS Question

Angular & jQuery selectors

I am adapting a quite recent application to angular.

In this app, I have a menu on the left. When the user clicks on a category in the left menu, the center part of the application is changed. Nothing complex here.

Before angular, I used to explicitly write the tags for each element on the left menu :

<li class="menu-element" data-category="home"><a href="#"><span class="glyphicon glyphicon-home"></span>Home</a>
</li>
<li class="menu-element" data-category="news"><a href="#"><span class="glyphicon glyphicon-comment"></span>News</a>
</li>
<li class="menu-element" data-category="brands"><a href="#"><span class="glyphicon glyphicon-tower"></span>Brands</a>
</li>
<li class="menu-element" data-category="activity"><a href="#"><span class="glyphicon glyphicon-flash"></span>Activity</a>
</li>
[...]


Then add behavior with jQuery :

$(".menu-element").click(function () {
[..]
});


Now, I rewrite it with angular. I declare the menu elements in a controller :

var ambasdrApp = angular.module('myApp', []);
myApp.controller('categoryListCtrl', function ($scope) {
$scope.categories = [
{'category': 'home', icon :'home', text: 'Home'},
{'category': 'news', icon :'comment', text: 'News'},
{'category': 'brands', icon :'tower', text: 'Brands'},
{'category': 'activity', icon :'flash', text: 'Activity'},

];
});


Then I replace the HTML tags with a ng-repeat directive :

<li ng-repeat="category in categories" class="menu-element ng-scope" data-category="{{category.category}}">
<a href="#"><span class="glyphicon glyphicon-{{category.icon}}"></span>{{category.text}}</a>
</li>


It works : the elements appear like before in the left menu.

Problem : The jQuery piece of code which adds "onClick" behavior does not work anymore. I suppose that when jQuery piece of code is executed, the menu elements do not exist yet.


  • one solution is to add an
    onClick=""
    in the
    ng-repeat
    directive. That would generate some
    <li onClick="[...]">
    but I think that it is evil. I would prefer to isolate the js in *.js files.

  • Another solution would be to execute the JQuery piece of code after that the
    ng-repeat
    directive is executed but I do not know how I can hook this.



How would you make it work?

Answer

For each object in your categories, you could add a new attribute called click which defines the function:

$scope.categories = [
  {'category': 'home',       icon :'home',     text: 'Home',  click:function() {...}},
...

And then in your markup, you use the ng-click directive and do something like:

<li ng-repeat="category in categories" class="menu-element ng-scope" data-category="{{category.category}}" ng-click="category.click()">