0

This is the scenario.

I have a Directive in my Html

<div class="row xsResponse" id="productGrid">
  <product product="product" ng-repeat="product in products"></product>
</div>

that product something like that

<div class="product">
  <!-- ... -->
</div>

and in the same page i have a Javascript that have to reference all the .product (class) in the #productGrid like this

document.querySelectorAll( '#productGrid .product' )).forEach( function( el ) {
  //.......
}

The problem is that the Javascript can see only the <product ...></product> tag and not his production. There is a way to call the Javascript after the ng-repeat?

Sorry if the question can appear not so clean and sorry for my bad english. Thanks for all your suggestions.

EDIT

For clarifications, here there is the javascript code.

<script>
        (function() {
            var body = document.body,
                dropArea = document.getElementById( 'drop-area' ),
                droppableArr = [], dropAreaTimeout;

            // initialize droppables
            [].slice.call( document.querySelectorAll( '#drop-area .drop-area__item' )).forEach( function( el ) {
                droppableArr.push( new Droppable( el, {
                    onDrop : function( instance, draggableEl ) {
                        // show checkmark inside the droppabe element
                        classie.add( instance.el, 'drop-feedback' );
                        clearTimeout( instance.checkmarkTimeout );
                        instance.checkmarkTimeout = setTimeout( function() { 
                            classie.remove( instance.el, 'drop-feedback' );
                        }, 800 );
                        // ...
                    }
                } ) );
            } );

            // initialize draggable(s)
            [].slice.call(document.querySelectorAll( '#grid .product' )).forEach( function( el ) {
                new Draggable( el, droppableArr, {
                    draggabilly : { containment: document.body },
                    onStart : function() {
                        // clear timeout: dropAreaTimeout (toggle drop area)
                        clearTimeout( dropAreaTimeout );
                        // show dropArea
                        classie.add( dropArea, 'show' );
                    },
                    onEnd : function( wasDropped ) {
                        var afterDropFn = function() {
                            // hide dropArea
                            classie.remove( dropArea, 'show' );
                        };

                        if( !wasDropped ) {
                            afterDropFn();
                        }
                        else {
                            // after some time hide drop area and remove class 'drag-active' from body
                            clearTimeout( dropAreaTimeout );
                            dropAreaTimeout = setTimeout( afterDropFn, 400 );
                        }
                    }
                } );
            } );
        })();
    </script>
Oxenarf
  • 200
  • 6
  • 23
  • 1
    u can use $timeout, but i dont understand why u dont launch what u need from directive itself – Petr Averyanov Feb 13 '15 at 02:34
  • @Oxenarf By "There is a way to call the Javascript after the ng-repeat?" do you mean to say that you want to be notified once ng-repeat has finished rendering? – amitthk Feb 13 '15 at 02:35
  • @amitthk i would like to start the javascript at the end of the ng-repeat because when it start it found only the tag and not the production of it – Oxenarf Feb 13 '15 at 02:38
  • @Oxenarf OK. I feel like your's is a mix an match of Angularjs & jQuery and it would be better to do it with Angularjs itself. Moreover, you can always use the `$scope.$last` property of ng-repeat as mentioned [in this](http://stackoverflow.com/questions/13471129/ng-repeat-finish-event) link to bind your action after ng-repeat has finished. – amitthk Feb 13 '15 at 02:47
  • what is your JQuery function actually doing? while you *can* use Angular and JQuery together, in practice it's very rare to do so, there is usually some way to accomplish your task without mixing frameworks. – Claies Feb 13 '15 at 02:51
  • To be more clear, every product have to become draggable and Draggable its a jquery class that take the element (the product in my case) and the droppables array like this new Draggable( elem, droppableArr, Some functions). I have to use this library compulsorily and not the angulars one. There is a way to bind this jquery class in the directive? – Oxenarf Feb 13 '15 at 03:42

1 Answers1

0

This is a common problem when trying to mix jQuery and Angular. The jQuery code will run before angular has added elements. Any elements added after the jQuery code is run won't get processed. The solution is a custom directive. A simple one would be:

.directive('product', function() {
   return {
      restrict: 'C',
      link: function(scope, el, attr) {
          //el is a jQuery object (assuming you've included jQuery)
          //you can run your custom jQuery logic on the element here
   };
})

The link function of this directive will get called for every element that has class="product".

It's functionally equivalent to:

document.querySelectorAll( '.product' )).forEach( function( el ) {
  //.......
});

Except that as a directive, it will get called even for elements that are added later (as long as they are added by angular).

Joe Enzminger
  • 11,110
  • 3
  • 50
  • 75