将函数传递给指令,然后使用参数调用它

Pass a function to a directive and then call it with parameters

我有一个指令(显示 youtube 视频)应该将一个函数作为一个属性,以便能够在 link 函数中启动它。

里面html我写的(玉)

div(ng-controller="videoPageCtrl")
    ...
    div(my-youtube,id='aaa',url='KEHxHr-Ih9w',on-change="doEventsOnChange")

我的控制器和指令如下所示

app
.directive('myYoutube', function($sce, $timeout) {
    return {
        restrict: 'A',
        scope: {
            url: '@',
            id: '@',
            onChange: '&',
        },
        link: function(scope) {
            $timeout(function() {
                scope.player = new YT.Player(scope.id, {
                    videoId: scope.url,
                    events: {
                        'onStateChange': function(state) {
                            console.log('state changed to', state, scope.id, scope.onChange);
                            scope.onChange(state, scope.id);
                        }
                    }
                });
            }, 5000);
        }
    };
})
.controller('videoPageCtrl', ['$scope', '$http', '$sce', function($scope, $http, $sce) {
    $scope.doEventsOnChange = function(state, id) {
        console.log(id, state, 'launched from controller!');
    };
}]);

问题是我无法通过 idstate 并启动 doEventsOnChange 函数。 结果在 chrome 开发控制台中我只能看到 state changed to 行,但没有 launched from controller! 行通过 idstate.

我做错了什么?

当你想在你的指令模板中使用函数时,你应该使用 onChange: '&',如果你只是想将函数传递给指令的范围,请使用 onChange: '='

The & binding allows a directive to trigger evaluation of an expression in the context of the original scope, at a specific time. Any legal expression is allowed, including an expression which contains a function call. Because of this, & bindings are ideal for binding callback functions to directive behaviors.

为了实现您的目标,您必须在 html

中使用此表达式
div(my-youtube,id='aaa',url='KEHxHr-Ih9w',on-change="doEventsOnChange(state,id)")

在你的指令中,传递参数时:

console.log('state changed to', state, scope.id, scope.onChange);
scope.onChange({state: state,id:scope.id});

请参阅 enter link description here

上的文档

& or &attr - provides a way to execute an expression in the context of the parent scope. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given and the isolate scope definition scope: { localFn:'&myAttr' }, the isolate scope property localFn will point to a function wrapper for the count = count + value expression. Often it's desirable to pass data from the isolated scope via an expression to the parent scope. This can be done by passing a map of local variable names and values into the expression wrapper fn. For example, if the expression is increment(amount) then we can specify the amount value by calling the localFn as localFn({amount: 22}).

希望对您有所帮助。