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

1
  • I think 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 stackoverflow.com/a/19890548/3867423. Hope this is helpful. Commented Apr 5, 2016 at 10:24

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

1 Comment

how does your link function look like? where have you called scope.onDrag() ? edit your mousemove function and add the scope.onDrag() to it.
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

2 Comments

I am not sure how that is working, when I try something similar my scope.vm is undefined.
can you post the code that you tried it with? check the Html in my jsBin. maybe, there is a difference there.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.