53

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

$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/...重定向到,然后用户将被重定向到身份验证服务。

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

4

7 回答 7

120

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')为真时才会发生。

于 2012-08-08T04:56:28.943 回答
20

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

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

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

请参阅文档相关来源

于 2015-02-19T03:18:24.597 回答
16

这是关闭深度链接的代码。它从 rootElement 禁用 click 事件处理程序。

angular.module('myApp', [])
   .run(['$location', '$rootElement', function ($location, $rootElement) {
      $rootElement.off('click');
}]);
于 2012-08-02T20:26:10.830 回答
2

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

Module.directive('a', function () {
    return {
        restrict: 'E',
        link: function(scope, element, attrs) {
            element.attr("target", "_self");
        }
    };
});
于 2014-09-10T18:22:08.227 回答
1

我现在用 angular 遇到过几次同样的问题,虽然我想出了两个功能性的解决方案,但都感觉像 hacks 而不是很“棱角分明”。

黑客#1:

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

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

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

黑客 #2

$route设置执行$window.location更改的Angular 。

// 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 页面加载一样。

于 2012-07-20T15:39:56.757 回答
0

在您的路线中尝试:

$routeProvider.otherwise({})

于 2012-07-20T20:57:06.650 回答
0

为了增加蜻蜓的答案,我发现限制 target="_self" 属性数量的最佳实践是永远不要将 ng-app 属性放在 body 标记上。通过这样做,您告诉 Angular, body 标签中的所有内容都是 Angular 应用程序的一部分。

如果您在不受角度影响的静态包装器中工作,请将您的 ng-app 属性放在仅围绕您的角度应用程序将要工作的位置的 div (或其他元素)上。这样你只会必须将 target='_self' 属性放在将成为 ng-app 元素的子元素的链接上。

<body>
    ... top markup ...
    <div ng-app="myApp">
        <div ng-view></div>
    </div>
    ... bottom markup ...
</body>
于 2014-10-14T23:00:47.730 回答