angular.js链接行为 - 禁用特定URL的深层链接

时间:2012-07-20 13:06:05

标签: angularjs

我有一个工作的Angular.js应用程序,启用了HTML5模式。

$location.Html5mode(true).hashbang("!");

我想要实现的是获取一些URL或<a>标签来执行正常的浏览行为,而不是使用HTML5历史记录API更改地址栏中的URL并使用Angular控制器处理它。

我有这个链接:

<a href='/auth/facebook'>Sign in with Facebook</a>
<a href='/auth/twitter'>Sign in with Twitter</a>
<a href='/auth/...'>Sign in with ...</a>

我希望浏览器将用户重定向到/auth/...,以便用户重定向到身份验证服务。

我有什么方法可以做到这一点吗?

7 个答案:

答案 0 :(得分:119)

添加target="_self"适用于Angular 1.0.1:

<a target="_self" href='/auth/facebook'>Sign in with Facebook</a>

记录此功能(https://docs.angularjs.org/guide/$location - 搜索'_self')

如果你很好奇,请查看角度来源(第5365行@ v1.0.1)。仅当!elm.attr('target')为真时才会发生点击劫持。

答案 1 :(得分:17)

Fran6co方法的替代方法是禁用$ locationProvider中的'rewriteLinks'选项:

$locationProvider.html5Mode({
    enabled: true,
    rewriteLinks: false
});

这将完成与调用$ rootElement.off('click')完全相同的事情,但不会干扰处理应用根元素上的点击事件的其他javascript。

请参阅docsrelevant source

答案 2 :(得分:16)

这是用于关闭所有深层链接的代码。它从rootElement中禁用click事件处理程序。

angular.module('myApp', [])
   .run(['$location', '$rootElement', function ($location, $rootElement) {
      $rootElement.off('click');
}]);

答案 3 :(得分:2)

要解决Nik的回答,如果您有很多链接并且不想为每个链接添加目标,您可以使用指令:

Module.directive('a', function () {
    return {
        restrict: 'E',
        link: function(scope, element, attrs) {
            element.attr("target", "_self");
        }
    };
});

答案 4 :(得分:1)

我现在用角度几次遇到了同样的问题,虽然我想出了两个功能解决方案,但感觉就像黑客而且不是很“有角”。

Hack#1:

window.location刷新绑定到链接的click事件。

<a 
  href=/external/link.html 
  onclick="window.location = 'http://example.com/external/link.html';"
>

这种方法的缺点和问题相当明显。

Hack#2

设置执行$route更改的角色$window.location

// Route
.when('/external', {
  templateUrl: 'path/to/dummy/template', 
  controller: 'external'
})

// Controller
.controller('external', ['$window', function ($window) {
  $window.location = 'http://www.google.com';
}])

我想你可以使用$routeParams或查询字符串扩展它,让一个控制器处理所有“外部”链接。

正如我所说,这些解决方案都不是非常令人满意,但如果你必须在短期内完成这项工作,他们可能会有所帮助。

另外,我非常希望看到Angular支持rel=external这类功能,就像jQueryMobile使用它来禁用ajax页面加载一样。

答案 5 :(得分:0)

在您的路线中尝试:

$routeProvider.otherwise({})

答案 6 :(得分:0)

要添加Dragonfly的答案,我发现最佳做法是限制目标数量=&#34; _self&#34;属性是从不将ng-app属性放在body标签上。通过这样做,您可以告诉角度,身体标签中的一切是角度应用程序的一部分。

如果您在不受角度影响的静态包装器中工作,请将ng-app属性放在div(或其他元素)上,该div仅包含您的角度应用程序将要使用的位置。这种方式你只需要把目标=&#39; _self&#39;链接的属性将是ng-app元素的子元素。

<body>
    ... top markup ...
    <div ng-app="myApp">
        <div ng-view></div>
    </div>
    ... bottom markup ...
</body>