如何从我的指令中调用控制器方法?

时间:2016-04-05 10:12:11

标签: javascript angularjs angularjs-directive angularjs-scope angularjs-controller

如何从我的onDrag()

调用控制器方法directive

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!");
};

警报未触发

2 个答案:

答案 0 :(得分:3)

您应该将该函数传递给您的指令,您可以这样做:

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函数中你可以调用scope.updateFn(),只要你想要执行控制器的onDrag函数。 你可以在这里找到更多关于这意味着什么的信息: https://thinkster.io/egghead/isolate-scope-am

答案 1 :(得分:0)

使用EntityController as vm时,vm可用作范围变量。因此,在原始代码中,您可以将控制器方法称为

scope.vm.onDrag(x, y)

请参阅工作示例here