Вот мое более полное решение, которое решает несколько вещей: @ Vigrond и @rahilwazir пропущены:
$routeUpdate
. $locationChangeSuccess
никогда не запускается, что приводит к предотвращению обновления маршрута next . app.run(['$rootScope', '$route', '$location', '$timeout', function ($rootScope, $route, $location, $timeout) {
['url', 'path'].forEach(function (method) {
var original = $location[method];
var requestId = 0;
$location[method] = function (param, reload) {
// getter
if (!param) return original.call($location);
# only last call allowed to do things in one digest cycle
var currentRequestId = ++requestId;
if (reload === false) {
var lastRoute = $route.current;
// intercept ONLY the next $locateChangeSuccess
var un = $rootScope.$on('$locationChangeSuccess', function () {
un();
if (requestId !== currentRequestId) return;
if (!angular.equals($route.current.params, lastRoute.params)) {
// this should always be broadcast when params change
$rootScope.$broadcast('$routeUpdate');
}
var current = $route.current;
$route.current = lastRoute;
// make a route change to the previous route work
$timeout(function() {
if (requestId !== currentRequestId) return;
$route.current = current;
});
});
// if it didn't fire for some reason, don't intercept the next one
$timeout(un);
}
return original.call($location, param);
};
});
}]);
Все, что нужно вашей функции edit
, - это принять другой аргумент, который изменит отредактированный элемент:
edit :: Int -> (a -> a) -> [a] -> Maybe [a]
edit 0 f (a:as) = Just (f a : as)
edit n (a:as) = do
let x = n - 1
y <- x `seq` edit x f as
return (a:y)
edit _ [] = Nothing