1

So I'm trying to use mootools to create a drag/drop cart as seen here: demo. I can get there code working just fine, but when I try to edit their html to look like the html beloe, it stops working. The css still applies as one would expect, and the div outside of the ng-repeat works fine. However, I'm pretty sure that the .addEvent in the mootools javascript can't 'find' the .item within the ng-repeat, so I am unable to grab any of the .items in ng-repeat.

Any ideas?

UPDATE: OK, it appears that the problem involves the domready event in the javascript. The angularjs hasn't loaded when that fires. I tried the load event, but this also fires before angularjs loads. Any other ideas for events? I'm using mousedown right now, but this means you have to click on one of the images before you can start dragging them, which is not optimal. In addition, the mousedown event seems to cause strange duplicates to appear in the cart sometimes, so I'll need to find a better method.

<div id="items">
    <div class="item">
        <p>test</p>
    </div>
  <div ng-repeat="post in posts">

    <div class="item">
        <img class="picImage" src="/static/imgs/{{post.picture}}" alt="Smiley face" height="128" width="128">
        <p>Shirt 1</p>
    </div>
  </div>
</div>
lnhubbell
  • 3,304
  • 5
  • 17
  • 22

2 Answers2

1

depends on how you attach the draggables. thing is, before ng-repeat renders through the $scope.$apply etc lifecycle for this part of the app, these elements won't be there.

// this code is wrong. 
$$('.item').addEvent('mousedown', function(event){
    event.stop();
... 
});

additionally, if the collection changes, mootools won't know to add the new click handlers.

you don't want to be waiting for content change by ng and re-applying mootools events, not a good idea.

you can either use: https://docs.angularjs.org/api/ng/directive/ngMousedown to bind the events to the collection elements, add a $scope.onMouseDown and move the logic there, letting angular deal with it internally:

<div ng-repeat="post in posts">
    <div class="item" ng-mousedown="onMouseDown($event, post, $index)">
        <img class="picImage" src="/static/imgs/{{post.picture}}" alt="Smiley face" height="128" width="128">
        <p>Shirt 1</p>
    </div>
</div>

with something like

$scope.onMouseDown = function($event, post, $index){
   // clone and do stuff


   // if you want to disable stuff, modify `post` etc, potentially can do $scope.$digest / $apply ...
};

... or you can use event delegation and bind like so:

$('items').addEvent('mousedown:relay(.items)', function(event){ 

    // ... do normal logic but no access to ng model here. can get dirty
});

event delegation (as above via relay) will work fine, as long as angular does not decide to re-render div#items due to whatever renders that part of your app. if it does, it will destroy the saved events. it also means you need to be able to see this element first to bind to it via mootools.

You may want to bind the event to your ng-app div to be safe and delegate to this one:

document.getElement('[ng-app]').addEvent('mousedown:relay(#items div.items)', fn);
Dimitar Christoff
  • 26,147
  • 8
  • 50
  • 69
0

Have you tried hooking on to the $viewContentLoaded event?

They talk about it here: AngularJs event to call after content is loaded

Community
  • 1
  • 1
Charlie L
  • 463
  • 2
  • 12