如何从指令中调用控制器方法?
How do I call a controller method from my directive?
如何从我的 directive
调用控制器方法 onDrag()
?
Html / (SVG)
<g ng-controller="EntityController as vm" draggable> ... </g>
指令
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);
}
}
};
}]);
控制器
app.controller("EntityController", function () {
var vm = this;
vm.onDrag = function () {
// do stuff
}
});
如果我没有正确执行此操作,我不介意改变我的方法,最好在同一 g 元素上的另一个 html 标记中传递要调用的方法,例如 on-drag="vm.onDrag()";
更新
根据建议我更改了代码:
<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!");
};
警报未触发
您应该将函数传递给您的指令,您可以这样做:
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);
}
}
};
}]);
然后你应该像这样将所需的函数传递给你的指令:
<g ng-controller="EntityController as vm" draggable update-fn="vm.onDrag()"> ... </g>
现在,在指令的 link 函数中,您可以在希望执行控制器的 onDrag 函数的任何地方调用 scope.updateFn() 。
您可以在此处找到有关这意味着什么的更多信息:
https://thinkster.io/egghead/isolate-scope-am
当您使用 EntityController as vm
时,vm 可用作作用域变量。因此,在您的原始代码中,您可以将控制器方法称为
scope.vm.onDrag(x, y)
查看工作示例here
如何从我的 directive
调用控制器方法 onDrag()
?
Html / (SVG)
<g ng-controller="EntityController as vm" draggable> ... </g>
指令
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);
}
}
};
}]);
控制器
app.controller("EntityController", function () {
var vm = this;
vm.onDrag = function () {
// do stuff
}
});
如果我没有正确执行此操作,我不介意改变我的方法,最好在同一 g 元素上的另一个 html 标记中传递要调用的方法,例如 on-drag="vm.onDrag()";
更新
根据建议我更改了代码:
<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!");
};
警报未触发
您应该将函数传递给您的指令,您可以这样做:
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);
}
}
};
}]);
然后你应该像这样将所需的函数传递给你的指令:
<g ng-controller="EntityController as vm" draggable update-fn="vm.onDrag()"> ... </g>
现在,在指令的 link 函数中,您可以在希望执行控制器的 onDrag 函数的任何地方调用 scope.updateFn() 。 您可以在此处找到有关这意味着什么的更多信息: https://thinkster.io/egghead/isolate-scope-am
当您使用 EntityController as vm
时,vm 可用作作用域变量。因此,在您的原始代码中,您可以将控制器方法称为
scope.vm.onDrag(x, y)
查看工作示例here