Comportamento do link angular.js – desabilite links diretos para URLs específicos

Eu tenho um aplicativo de trabalho Angular.js com o modo HTML5 ativado.

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

O que eu quero alcançar é obter algumas URLs ou tags para fazer o comportamento normal de navegação, em vez de alterar o URL na barra de endereço usando a API do histórico de HTML5 e manipulá-lo usando controladores angulares.

Eu tenho esses links:

 Sign in with Facebook Sign in with Twitter Sign in with ... 

E quero que o navegador redirecione o usuário para https://stackoverflow.com/auth/... para que o usuário seja redirecionado para um serviço de autenticação.

Existe alguma maneira de fazer isso?

Adicionando target="_self" funciona no Angular 1.0.1:

 Sign in with Facebook 

Este recurso está documentado ( https://docs.angularjs.org/guide/$location – procure por ‘_self’)

Se você está curioso, olhe para a fonte angular (linha 5365 @ v1.0.1). O seqüestro de cliques acontece somente se !elm.attr('target') for verdadeiro.

Uma alternativa ao método de Franço é desabilitar a opção ‘rewriteLinks’ no $ locationProvider:

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

Isso realizará exatamente a mesma coisa que chamar $ rootElement.off (‘clique’), mas não interferirá em outro javascript que lide com events de cliques no elemento raiz do seu aplicativo.

Veja os documentos e a fonte relevante

Este é o código para desligar todos os links profundos. Desativa o manipulador de events click do rootElement.

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

Eu me deparei com o mesmo problema algumas vezes agora com o angular, e enquanto eu encontrei duas soluções funcionais, ambas se parecem com hacks e não muito “angulares”.

Corte 1:

Vincule uma atualização de window.location ao evento de click do link.

  

A desvantagem e os problemas com essa abordagem são bastante óbvios.

Hack # 2

Configure $route s angulares que executam uma alteração $window.location .

 // Route .when('/external', { templateUrl: 'path/to/dummy/template', controller: 'external' }) // Controller .controller('external', ['$window', function ($window) { $window.location = 'http://www.google.com'; }]) 

Eu imagino que você poderia estender isso usando $routeParams ou strings de consulta para ter um controlador lidando com todos os links “externos”.

Como eu disse, nenhuma dessas soluções é muito satisfatória, mas se você precisar fazer isso funcionar a curto prazo, elas podem ajudar.

Em uma nota lateral, eu realmente gostaria de ver o suporte Angular rel=external para esse tipo de funcionalidade, da mesma forma que o jQueryMobile o usa para desabilitar o carregamento de páginas do ajax.

Para resolver a resposta do Nik, se você tem muitos links e não quer adicionar alvos a cada um deles, você pode usar uma diretiva:

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

Para adicionar à resposta da Dragonfly, uma prática recomendada que eu encontrei para limitar o número de atributos target = “_ self” é nunca colocar o atributo ng-app na tag body. Ao fazer isso, você está dizendo que tudo nas tags body faz parte do aplicativo angular.

Se você estiver trabalhando em um wrapper estático que não deve ser afetado pelo angular, coloque o atributo ng-app em um div (ou outro elemento) que rodeia apenas o local em que seu aplicativo angular estará trabalhando. Dessa forma, você só tem que colocar o atributo target = ‘_ self’ em links que serão filhos do elemento ng-app.

  ... top markup ... 
... bottom markup ...

Nas suas rotas, tente:

$routeProvider.otherwise({})