1

How do I get jQuery to access elements with a class that was given by Angular in an ng-repeat loop?

(If I execute the same jQuery command $('.active').css('color','red'); in the console of Firebug, it works.)

enter image description here

<!DOCTYPE html>
<html ng-app="mainModule">
    <head>
        <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
        <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js"></script>
    </head>
    <body>

        <div ng-controller="mainController">
            <div class="active">aaa</div>
            <div class="active">bbb</div>
            <div ng-repeat="project in projects">
                <div class="active">{{project}}</div>
            </div>
        </div>
        <script>
            angular.module('mainModule', [])
                    .controller('mainController', function ($scope) {
                        $scope.projects = ['111', '222', '333', '444'];
                        $('.active').css('color','red');
                    });
        </script>  
    </body>
</html>
Edward Tanguay
  • 189,012
  • 314
  • 712
  • 1,047
  • because when controller intialized at that time `ng-repeat` haven't render its content.. you need to run your code one digest cycle later to make sure `ng-repeat` has done its rendering like `$timeout(function(){ $('.active').css('color','red'); })`, though its not angular way of manipulating DOM from controller.. – Pankaj Parkar May 30 '16 at 11:53
  • 3
    Sounds like an XY problem. What is the higher level objective ... just change style? Can use `ng-style`. My guess is the example is over simplified. Should never have any DOM code in controller. – charlietfl May 30 '16 at 11:53
  • The jQuery works; the problem is that it is not finding the nodes created from the `ng-repeat` because when the jQuery line runs, Angular hasn't rendered them yet! Timeouts are a solution to this - but it is giving me the creeps in terms of maintainability and code clarity. What are you trying to accomplish? Maybe there is another way? – Nikos Paraskevopoulos May 30 '16 at 11:54
  • You should not use dom manipulation in controller :) You can create a custom directive and pass it as a attribute in the "
    {{project}}
    " and you can make whatever the dom manipulation inside the link function of highlight directive!.
    – sajan May 30 '16 at 11:59
  • Yes, I generally keep my Angular code jQuery-free, but I (1) need this immediately to be able to set focus dynamically on one of many input fields which is defined by Angular, and (2) I just want to have skills to quickly add a jQuery fix if I need to. I remember I used to do this with $scope.apply(), I think, and I want to get a working example again. – Edward Tanguay May 30 '16 at 12:03
  • Did you try `ng-focus`? Anything like what you are showing needs to be done in directive where each individual element is exposed and assures the element exists when the code is run. So rather than doing it on whole class like in jQuery you would only act upon that specific element based on its scope model. `element.somejQueryMethod()` – charlietfl May 30 '16 at 12:13
  • `ng-focus` as far as I understand is an event which triggers when a field gets focus, not a way to set the focus in a field, e.g. ``. I could only find custom directives of 15+ lines to get a simply set focus in an input field, and so I wanted to simply do it with jQuery. – Edward Tanguay May 30 '16 at 12:16
  • OK..well approach would still be do it in directive after evaluating scope for each specific element. Or by passing in something from controller to match to a property in that element level scope – charlietfl May 30 '16 at 12:19
  • See [this](http://stackoverflow.com/questions/15207788/calling-a-function-when-ng-repeat-has-finished) question. – Alexander Kravets May 30 '16 at 12:27
  • @EdwardTanguay It is really simple :) try my way it should work! – sajan May 30 '16 at 12:50

0 Answers0