将参数从指令传递给回调

时间:2021-03-15 20:39:15

I'm trying to define a directive sortable which wraps jqueryui's sortable plugin.

我正在尝试定义一个包装jqueryui的可排序插件的指令sortable。

The angular code is:

角度代码是:

module.directive('sortable', function () {
    return function (scope, element, attrs) {
        var startIndex, endIndex;
        $(element).sortable({
            start:function (event, ui) {
                startIndex = ui.item.index();
            },
            stop:function (event, ui) {
                endIndex = ui.item.index();
                if(attrs.onStop) {
                    scope.$apply(attrs.onStop, startIndex, endIndex);
                }
            }
        }).disableSelection();
    };
});

The html code is:

HTML代码是:

<div ng-controller="MyCtrl">
    <ol sortable onStop="updateOrders()">
         <li ng-repeat="m in messages">{{m}}</li>
    </ol>
</div>

The code of MyCtrl:

MyCtrl的代码:

function MyCtrl($scope) {
    $scope.updateOrders = function(startIndex, endIndex) {
        console.log(startIndex + ", " + endIndex);
    }
}

I want to get the startIndex and endIndex in my callback updateOrders and do something with them, but it prints:

我想在我的回调updateOrders中获取startIndex和endIndex并对它们执行某些操作,但它会打印:

undefined, undefined

How to pass these parameters to my callbacks? Is my approach correct?

如何将这些参数传递给我的回调?我的方法是否正确?

4 个解决方案

#1


16  

scope.$apply accepts function or string. In this case using function would be simpler:

scope。$ apply接受函数或字符串。在这种情况下,使用函数会更简单:

  scope.$apply(function(self) {
    self[attrs.onStop](startIndex, endIndex);
  });

Don't forget to change your html code to:

不要忘记将您的HTML代码更改为:

<ol sortable onStop="updateOrders">

(Removed the ())

(删除了())

#2


19  

This fiddle shows hot callback from a directive passing parameters. Main trick is to use the scope to pass a function. http://jsfiddle.net/pkriens/Mmunz/7/

这个小提琴显示来自传递参数的指令的热回调。主要技巧是使用范围来传递函数。 http://jsfiddle.net/pkriens/Mmunz/7/

var myApp = angular.module('myApp', []).
directive('callback', function() {
    return { 
        scope: { callback: '=' },
        restrict: 'A',
        link: function(scope, element) {
            element.bind('click', function() {
                scope.$apply(scope.callback('Hi from directive '));
            })
        }
    };
})

function MyCtrl($scope) {
    $scope.cb = function(msg) {alert(msg);};
}

Then the html looks like for example:

然后html看起来像例如:

<button callback='cb'>Callback</button>

#3


13  

Alternative 1

备选方案1

If you don't have an isolate scope for this directive, I would use the $parse service for that:

如果你没有这个指令的隔离范围,我会使用$ parse服务:

In the controller:

在控制器中:

...
$scope.getPage = function(page) {

   ...some code here...

}

In the view:

在视图中:

<div class="pagination" current="6" total="20" paginate-fn="getData(page)"></div>

In the directive:

在指令中:

if (attr.paginateFn) {
   paginateFn = $parse(attr.paginateFn);
   paginateFn(scope, {page: 5})
}

Alternative 2

备选方案2

Now, if you have an isolate scope, you can pass parameters to it as a named map. If your directive is defined like this:

现在,如果您有隔离范围,则可以将参数作为命名映射传递给它。如果您的指令定义如下:

scope: { paginateFn: '&' },

link: function (scope, el) {
   scope.paginateFn({page: 5});
}

#4


0  

taking @Peter Kriens answser a step further you can just check for the name of a on the scope and call it directly.

将@Peter Kriens的答案更进一步,您可以检查范围上的名称并直接调用它。

var myApp = angular.module('myApp', []).
directive('anyOldDirective', function() {
    return { 
        link: function(scope, element) {
            element.bind('click', function() {
                if (scope.wellKnownFunctionName) {
                      scope.wellKnownFunctionName('calling you back!'); 
                } else {
                      console.log("scope does not support the callback method 'wellKnownFunctionName');
                }
            })
        }
    };
})

function MyCtrl($scope) {
    $scope.wellKnownFunctionName= function(a) {console.log(a);};
}

#1


16  

scope.$apply accepts function or string. In this case using function would be simpler:

scope。$ apply接受函数或字符串。在这种情况下,使用函数会更简单:

  scope.$apply(function(self) {
    self[attrs.onStop](startIndex, endIndex);
  });

Don't forget to change your html code to:

不要忘记将您的HTML代码更改为:

<ol sortable onStop="updateOrders">

(Removed the ())

(删除了())

#2


19  

This fiddle shows hot callback from a directive passing parameters. Main trick is to use the scope to pass a function. http://jsfiddle.net/pkriens/Mmunz/7/

这个小提琴显示来自传递参数的指令的热回调。主要技巧是使用范围来传递函数。 http://jsfiddle.net/pkriens/Mmunz/7/

var myApp = angular.module('myApp', []).
directive('callback', function() {
    return { 
        scope: { callback: '=' },
        restrict: 'A',
        link: function(scope, element) {
            element.bind('click', function() {
                scope.$apply(scope.callback('Hi from directive '));
            })
        }
    };
})

function MyCtrl($scope) {
    $scope.cb = function(msg) {alert(msg);};
}

Then the html looks like for example:

然后html看起来像例如:

<button callback='cb'>Callback</button>

#3


13  

Alternative 1

备选方案1

If you don't have an isolate scope for this directive, I would use the $parse service for that:

如果你没有这个指令的隔离范围,我会使用$ parse服务:

In the controller:

在控制器中:

...
$scope.getPage = function(page) {

   ...some code here...

}

In the view:

在视图中:

<div class="pagination" current="6" total="20" paginate-fn="getData(page)"></div>

In the directive:

在指令中:

if (attr.paginateFn) {
   paginateFn = $parse(attr.paginateFn);
   paginateFn(scope, {page: 5})
}

Alternative 2

备选方案2

Now, if you have an isolate scope, you can pass parameters to it as a named map. If your directive is defined like this:

现在,如果您有隔离范围,则可以将参数作为命名映射传递给它。如果您的指令定义如下:

scope: { paginateFn: '&' },

link: function (scope, el) {
   scope.paginateFn({page: 5});
}

#4


0  

taking @Peter Kriens answser a step further you can just check for the name of a on the scope and call it directly.

将@Peter Kriens的答案更进一步,您可以检查范围上的名称并直接调用它。

var myApp = angular.module('myApp', []).
directive('anyOldDirective', function() {
    return { 
        link: function(scope, element) {
            element.bind('click', function() {
                if (scope.wellKnownFunctionName) {
                      scope.wellKnownFunctionName('calling you back!'); 
                } else {
                      console.log("scope does not support the callback method 'wellKnownFunctionName');
                }
            })
        }
    };
})

function MyCtrl($scope) {
    $scope.wellKnownFunctionName= function(a) {console.log(a);};
}