0

How do I call a controller method onDrag() from my directive?

Html / (SVG)

<g ng-controller="EntityController as vm" draggable> ... </g>

Directive

app.directive('draggable', ['$document', function($document) {
    return {
        link: function(scope, element, attr) {
            var startX = 0, startY = 0, x = 0, y = 0;

            element.on('mousedown', function(event) {
                event.preventDefault();
                startX = event.pageX - x;
                startY = event.pageY - y;
                $document.on('mousemove', mousemove);
                $document.on('mouseup', mouseup);
            });

            function mousemove(event) {
                y = event.pageY - startY;
                x = event.pageX - startX;
                element.attr("transform", "translate(" + x + "," + y + ")");
                // I want to call the controllers onDrag() here
                // possibly passing in values
            }

            function mouseup() {
                $document.off('mousemove', mousemove);
                $document.off('mouseup', mouseup);
            }
        }
    };
}]);

Controller

app.controller("EntityController", function () {
    var vm = this;

    vm.onDrag = function () {
        // do stuff
    }  
});

If I am not doing this correctly I do not mind changing my approach, it may be better to pass in the method to be called in another html tag on the same g element, like a on-drag="vm.onDrag()";

Update

As per suggestions I have changed the code :

<g ng-controller="EntityController as vm" on-drag="vm.drag()" draggable>

app.directive('draggable', ['$document', function ($document) {
        return {
            scope: {
                onDrag: '&'
            },
            link: ...
        }
}

vm.drag = function() {
    alert("you dragged something!");
};

The alert is not firing

sprocket12
  • 5,368
  • 18
  • 64
  • 133
  • I think http://stackoverflow.com/a/18378602/3867423 answers your question. This answer explains how to pass callbacks to your directive (in your case `onDrag()` would be the callback. If you plan to pass parameters to the callback when calling it in the controller, see this answer http://stackoverflow.com/a/19890548/3867423. Hope this is helpful. – Thylossus Apr 05 '16 at 10:24

2 Answers2

3

You should pass the function to your directive you can do it like this :

app.directive('draggable', ['$document', function($document) {
return {
    scope: {
        updateFn: '&'
    },
    link: function(scope, element, attr) {
        var startX = 0, startY = 0, x = 0, y = 0;

        element.on('mousedown', function(event) {
            event.preventDefault();
            startX = event.pageX - x;
            startY = event.pageY - y;
            $document.on('mousemove', mousemove);
            $document.on('mouseup', mouseup);
        });

        function mousemove(event) {
            y = event.pageY - startY;
            x = event.pageX - startX;
            element.attr("transform", "translate(" + x + "," + y + ")");
            scope.updateFn(); // this fires the callback
        }

        function mouseup() {
            $document.off('mousemove', mousemove);
            $document.off('mouseup', mouseup);
        }
    }
};
}]);

And then you should pass the required function to your directive like this :

<g ng-controller="EntityController as vm" draggable update-fn="vm.onDrag()"> ... </g>

now in link function of your directive you can call scope.updateFn() wherever you want the controller's onDrag function executed. you can find more information on what this means here: https://thinkster.io/egghead/isolate-scope-am

sprocket12
  • 5,368
  • 18
  • 64
  • 133
alimfazeli
  • 101
  • 5
  • how does your link function look like? where have you called scope.onDrag() ? edit your mousemove function and add the scope.onDrag() to it. – alimfazeli Apr 05 '16 at 11:00
0

When you use EntityController as vm, vm is available as a scope variable. So, in your original code, you could have called controller method as

scope.vm.onDrag(x, y)

See the working example here

Bhabishya Kumar
  • 731
  • 3
  • 7