使用scope。$ eval将参数传递到指令回调中

时间:2018-06-22 16:12:16

标签: angularjs angularjs-directive

我有一个鼠标滚轮指令,当鼠标移动时会被调用。但是如何在回调过程中传递滚动位置?

export function ngMouseWheelDown() {
    return function (scope: angular.IScope, element, attrs) {
        element.bind("DOMMouseScroll mousewheel onmousewheel",
            function (event) {

                // cross-browser wheel delta
                var event = window.event || event; // old IE support
                var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail)));

                if (delta < 0) {
                    scope.$apply(function () {
                        scope.$eval(attrs.ngMouseWheelDown);
                    });
                }
            });
    }
}

HTML

<div ng-mouse-wheel-up="$ctrl.scrollEvent($event)"
     ng-mouse-wheel-down="$ctrl.scrollEvent($event)"
     style="overflow-y: auto;">

2 个答案:

答案 0 :(得分:1)

使用locals方法的$eval参数:

export function ngMouseWheelDown() {
    return function (scope: angular.IScope, element, attrs) {
        element.bind("DOMMouseScroll mousewheel onmousewheel",
            function (event) {

                // cross-browser wheel delta
                var event = window.event || event; // old IE support
                var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail)));

                if (delta < 0) {
                    var locals = {$event: event, $delta: delta};
                    scope.$apply(function () {
                        scope.$eval(attrs.ngMouseWheelDown, locals);
                    });
                }
            });
    }
}

用法:

<div ng-mouse-wheel-up="$ctrl.scrollEvent($event, $delta)"
     ng-mouse-wheel-down="$ctrl.scrollEvent($event, $delta)"
     style="overflow-y: auto;">

有关更多信息,请参见 -AngularJS scope.$eval API Reference

答案 1 :(得分:0)

您不需要评估。 AngularJs具有绑定功能-能够评估并从父级到子级(从控制器到指令)传递您想要的任何东西,您需要做的就是创建如下范围的指令:

return {
    scope: {handler: '='},
    link: function ($scope, $elem, $attrs){
                 element.bind("", function(event){
                         ...
                         $scope.handler(...);
                  })
           }
}

但是正如@georgeawg所述,创建隔离范围并不总是一个好主意,因为在一个元素中只能有一个隔离范围。

因此,为此,您可以使用$parse服务从以下属性评估您的回调:

['$parse', function myDirective($parse){return {
     link: function myDirecitveLink($scope, $elem, $attrs) {
               // this is the only expression that can be evaluated whenever 
               // you need
               const handlerExpression = $parse($attrs['myHandlerName']); 

               // this is real handler you can call and pass params
               const readlHandler = handlerExpression($scope); 

               // now you can call your handler with desired params
               realHandler(...);
    }
}}]

这还将节省您一些CPU,因为您不会创建新的观察程序,并且可以完全管理您需要何时和多少次来评估表达式。

@georgeawg感谢您的评论