3

I am writing an application on Ruby on Rails using AngularJS for resource management (dynamic loading etc) and JQuery for effects like accordion, fade in-out etc.

When I want to display my data on a page I query the data from the resource using an Angular JS controller and then I display them accordingly using ng-repeat and ng-show. When this is completed I need to setup the JQuery onclick events to add effects (Accordion to be specific). Unfortunately I cannot find an event that will be called when all DOM components are loaded and when all Angular digestion is completed. Meaning the JQuery's onload event is not working and also trying to use a directive like ng-repeat finish event that one produces an error that digest already in progress.

AngularJS is pretty new and I am having difficulties finding good documentation.

Does any one have any ideas? Thanks!

Community
  • 1
  • 1
jkotzi
  • 171
  • 1
  • 6

2 Answers2

3

You must wait until ng-repeat has completed before using jQuery to init Accordion.

Here is a directive for doing that ( http://jsfiddle.net/tQw6w/ ); it calls a specified function when true:

.directive('repeatDone', function() {
    return function(scope, element, attrs) {
        if (scope.$last) { // all are rendered
            scope.$eval(attrs.repeatDone);
        }
    }
})

and the html:

<ul>
    <li ng-repeat="feed in feedList" repeat-done="layoutDone()" ng-cloak>
        <a href="{{feed}}" title="view at {{feed | hostName}}" data-toggle="tooltip">{{feed | strip_http}}</a>
    </li>
</ul>

and the function in the controller:

$scope.layoutDone = function() {
    $timeout(function() { $('a[data-toggle="tooltip"]').tooltip(); }, 0); // wait...
}

I have found that $timeout with interval=0 before doing DOM manipulation is required, like initializing tooltips in the fiddle, or your Accordion.

Answered previously here: https://stackoverflow.com/a/16142327/2275421

Community
  • 1
  • 1
Joseph Oster
  • 5,507
  • 1
  • 20
  • 11
2

You can put your jQuery code inside $apply, like this:

$scope.$apply(function() {
    // jQuery stuff here
});

if it fires error like "digest in progress", you can use setTimeout:

setTimeout(function(){
    $scope.$apply(function() {
        // jQuery stuff here
    });
 });

Directive way:

//Directive - STRART
.directive("yourNameHere", function() {
    return function(scope, element, attrs) {
        $(element).jQueryStuffHere();
    };
})//Directive -END

Hope it helps, Cheers

Jason Aller
  • 3,541
  • 28
  • 38
  • 38
Vova Lando
  • 558
  • 3
  • 15