Передача параметров из директивы в обратный вызов
Я пытаюсь определить директиву sortable
, которая обертывает jqueryui sortable plugin.
Код angular:
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();
};
});
Код html:
<div ng-controller="MyCtrl">
<ol sortable onStop="updateOrders()">
<li ng-repeat="m in messages">{{m}}</li>
</ol>
</div>
Код MyCtrl
:
function MyCtrl($scope) {
$scope.updateOrders = function(startIndex, endIndex) {
console.log(startIndex + ", " + endIndex);
}
}
Я хочу получить startIndex
и endIndex
в своем обратном вызове updateOrders
и сделать с ними что-то, но он печатает:
undefined, undefined
Как передать эти параметры моим обратным вызовам? Правильно ли мой подход?
Ответы
Ответ 1
scope.$apply
принимает функцию или строку.
В этом случае использование функции будет проще:
scope.$apply(function(self) {
self[attrs.onStop](startIndex, endIndex);
});
Не забудьте изменить свой HTML-код на:
<ol sortable onStop="updateOrders">
(Удалено ()
)
Ответ 2
Эта скрипта показывает горячий обратный вызов из параметров передачи директивы. Основной трюк заключается в том, чтобы использовать область действия для передачи функции.
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);};
}
Затем html выглядит, например:
<button callback='cb'>Callback</button>
Ответ 3
Альтернатива 1
Если у вас нет области выделения для этой директивы, я бы использовал для этого службу $parse:
В контроллере:
...
$scope.getPage = function(page) {
...some code here...
}
В представлении:
<div class="pagination" current="6" total="20" paginate-fn="getData(page)"></div>
В директиве:
if (attr.paginateFn) {
paginateFn = $parse(attr.paginateFn);
paginateFn(scope, {page: 5})
}
Альтернатива 2
Теперь, если у вас есть область выделения, вы можете передать ему параметры как именованные карты. Если ваша директива определяется следующим образом:
scope: { paginateFn: '&' },
link: function (scope, el) {
scope.paginateFn({page: 5});
}
Ответ 4
принимая @Peter Kriens answser еще один шаг, вы можете просто проверить имя a в области и вызвать его напрямую.
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);};
}