I\'m trying to animate a user selecting items from different sets of items. The item should animate from the clicked set to it\'s new position in list of selected items.
This solution is an improvement in that it eliminates the need to add information to the scope in the Purchase function and it avoids mixing model data and UI details by using a "source" directive and storing origin information in a controller property. The example is simplified and can of course be improved. The key point is that the data required to manage the process is never exposed via the scope.
If the target element is subject to being removed from the DOM (i.e it's part of an ng-repeat, then this solution would have to be modified slightly to calculate and store the animation start positions as part of the monitor.click handler rather than store the target element itself.
The method of animation seems to me to be arbitrary. This example uses the OP's jqueryUI animation method, but it would work just as well with css transitions or using $animate.
A full example is here
angular.module('app', [])
.controller('main', function($scope) {
$scope.products = [{},{}];
$scope.purchased = [{}];
$scope.Purchase = function() {
$scope.purchased.push({});
};
})
.directive('source', function(){
return {
controller: function($scope) {
}
};
})
.directive('originator', function(){
return{
require: '^source',
priority: 1,
link:{
pre: function(scope, element, attr, ctrl){
element.on('click', function(evt){
ctrl.target = evt.target;
});
}
}
};
})
.directive('sink', function(){
return {
require: '^source',
link: function(scope, element, attr, ctrl){
var target = ctrl.target;
if(target){
var $target = $(target);
//animate from target to current position
element.position({
my: 'center',
at: 'center',
of: $target,
using: function(pos, data) {
$(this).css(pos);
$(this).animate({
top: 0,
left: 0
});
}
});
ctrl.target = undefined;
}
}
};
});