0

我的主控制器的目标之一是防止用户访问其他用户的网址。监听 $locationChangeStart 并使用它的事件 preventDefault 方法非常有效。不幸的是,调用此方法有一个奇怪的副作用,即以某种方式“中断”函数“handleNotification”的工作,该函数的目标是在 2 秒内通知用户她或他做了非法的事情。如果我注释掉 event.preventDefault(),一切都会按预期进行。所以我的问题是:“默认” preventDefault 的“范围”是什么,它可以防止我没有想到并且使 handleNotification 功能无法正常工作?

$scope.$on('$locationChangeStart', function(event, newUrl, oldUrl) {
    ifUserIs('loggedIn', function() {
        if (newUrl.split('#/users/')[1] !== $scope.user.userId) {
            handleNotification('alert', 'You are not allowed to go here.');
            event.preventDefault();
        }
    });
});

function handleNotification (type, message) {

$scope.notice = {
    content: message,
    type: type
};

$timeout(function() {
    delete $scope.notice;
    return true;
    }, 2000);
}
4

1 回答 1

0

下面更新

好的。问题出在其他地方。在相关的jsfiddle 中,一切正常。在找到导致这种奇怪行为的原因后,我会告诉你。

<html ng-app="mapApp">
    <div ng-controller="mainCtrl">
        <global-error message="{{notice.content}}"></global-error>
    </div>

</html>

和代码。

var mapApp = {};
mapApp = angular.module('mapApp', []);
mapApp.controller('mainCtrl', function ($scope, $location, $timeout) {
    $location.path('users/2')

$scope.$on('$locationChangeStart', function (event, newUrl, oldUrl) {

    handleNotification('alert', 'You are not allowed to go here.');
    event.preventDefault();

});

function handleNotification(type, message) {
    $scope.notice = {
        content: message,
        type: type
    };

    $timeout(function () {
        delete $scope.notice;
        console.log('deleted');
        return true;
    }, 2000);

   $scope.$digest();

}

});

mapApp.directive('globalError', function () {
    return {
        restrict: 'E',
        scope: {
            message: '@',
            type: '@'
        },
        template: "<div class=\"alert-box {{type}}\">\
                <p>\
                    {{message}}\
                </p>\
            </div>"
    };
});

更新 好。更进一步。问题仍然存在。现在我知道更改浏览器中的路径与通过放入$location.path('users/2')代码更改 url 不同(见上文)。虽然$location.path('users/2')按预期工作,但手动更改浏览器地址栏中的路径只会使地址跳回旧地址而不显示通知。所以event.preventDefault()工作正常但 handleNotification('alert', 'You are not allowed to go here.')不是。奇怪的。

更新 2 添加$scope.$digest()handleNotification函数的末尾就可以了。

于 2013-11-09T21:47:44.347 回答