angularjs - bootstrap - Cómo evitar el redireccionamiento de<a href==##something"> en Angular Js1.2
ui bootstrap tpls (9)
En general, puede definir funciones en el prototipo de todos los ámbitos utilizando el rootscope. Agregue ng-click en sus etiquetas de anclaje y pase el evento $ a los controladores de rootscope. Angular puede enviar el evento de origen también con ng-click:
<a ng-click="tabclick($event)">
en un bloque de ejecución de su módulo, puede configurar una función tabClick en $ rootScope
$rootScope.tabclick = function ($event) { $event.preventDefault(); }
Esto funcionará para cualquier ámbito y no tendrá que verificar los identificadores de elementos específicos.
Ejemplo de violín: http://jsfiddle.net/stto3703/wQe6P/
Aclamaciones
Estaba usando AngularJs-1.0.7 y Bootstrap en mi aplicación. Recientemente migré de AngularJs-1.0.7 a AngularJs-1.2. Estoy usando los Acordeones y Pestañas de Bootstrap.
El código HTML de la pestaña contiene <a href="#id_for_content">
como se muestra a continuación.
<ul id="myTab" class="nav nav-tabs">
<li class="active"><a href="#firstTab" data-toggle="tab">Home</a></li>
<li><a href="#secondTab" data-toggle="tab">Profile</a></li>
</ul>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade in active" id="firstTab">
<p>Content for first tab.</p>
</div>
<div class="tab-pane fade" id="secondTab">
<p>Content For second tab.</p>
</div>
</div>
En las versiones anteriores de Angular, el cambio de ruta solo ocurre si le damos una etiqueta de anclaje como <a href="#/firstTab">
. Pero AngularJs-1.2 redirige <a href="#firstTab">
. No considera el /
entre #
y firstTab
. Por lo tanto, al hacer clic en la pestaña, se redirige a http://web_url/#/firstTab
. ¿Cómo resolver este problema?
Mi solución
He encontrado una solución para este problema. Escribí una directiva para una etiqueta. En esa directiva he comprobado el atributo href. Si coincide evita su comportamiento por defecto. Compruebe el siguiente código.
app.directive(''a'', function() {
return {
restrict: ''E'',
link: function(scope, elem, attrs) {
if(attrs.href === ''#firstTab''|| attrs.href === ''#secondTab''){
elem.on(''click'', function(e){
e.preventDefault();
});
}
}
};
});
Pero el problema con este método es que tengo que verificar todos los identificadores de pestañas o identificadores de acordeón aquí. Si uso identificadores dinámicos para ellos, no es posible verificar la directiva.
Si puede encontrar una mejor solución, háganoslo saber.
He estado teniendo este problema por un tiempo también, y solo he tropezado con esta pregunta (y su propia respuesta). Resulta que estás casi correcto con tu solución, solo una pequeña modificación hace que funcione como te gustaría.
Además del problema que tenía con las pestañas, también me encontré con este problema con los enlaces desplegables: estaban navegando fuera de la página actual al hacer clic, en lugar de desplegar el menú, y de hecho, este problema está presente en cualquier enlace que haya sido diseñado para alternar algo, es decir, con el conjunto de atributos de conmutación de datos.
Por lo tanto, una pequeña modificación en su código para verificar la presencia del atributo ''toggle'' lo resuelve para mí:
app.directive(''a'', function() {
return {
restrict: ''E'',
link: function(scope, elem, attrs) {
if(attrs.toggle){
elem.on(''click'', function(e){
e.preventDefault();
});
}
}
};
});
¡Espero que esto ayude!
Puede usar ng-click para llamar a una función en su JS. En esa función, use el método preventDefault
del evento, y use el método hash
$location
para cambiar el hash en su URL.
Si no tiene éxito con las respuestas anteriores, podría intentar usar $ timeout ... En este caso, he usado las pestañas de AngularUI ...
vm.removeUserTab = function (user) {
$timeout(function () {
vm.activeTab = 0;
var index = vm.userTabs.indexOf(user);
vm.userTabs.splice(index, 1);
});
};
Solo agrega esto a tus enlaces:
target="_self"
Y estas listo;)
Solo me gustaría hacerle saber que hay otra solución para resolver este problema (sin definir la función en los controladores).
Puede crear una directiva que impida el comportamiento predeterminado del navegador (que en realidad está cambiando la URL):
var PreventDefault = function () {
var linkFn = function (scope, element, attrs) {
$(element).on("click", function (event){
event.preventDefault();
});
};
return {
restrict: ''A'',
link: linkFn
}
};
y luego simplemente agregue la directiva a cada a
elementos responsables de alternar una pestaña como esta:
<ul id="myTab" class="nav nav-tabs">
<li class="active"><a href="#firstTab" prevent-default data-toggle="tab">Home</a></li>
<li><a href="#secondTab" prevent-default data-toggle="tab">Profile</a></li>
</ul>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade in active" id="firstTab">
<p>Content for first tab.</p>
</div>
<div class="tab-pane fade" id="secondTab">
<p>Content For second tab.</p>
</div>
</div>
Su solución en su pregunta funciona, pero para evitar tener que verificar la identificación de cada ancla, cambie
if (attrs.href === ''#firstTab''|| attrs.href === ''#secondTab'')
a
if (attrs.href && attrs.href.indexOf(''#'') > -1)
Directiva:
.directive(''a'', function () {
return {
restrict: ''E'',
link: function (scope, elem, attrs) {
if (attrs.href && attrs.href.indexOf(''#'') > -1) {
elem.on(''click'', function (e) {
e.preventDefault();
});
}
}
};
})
créditos para https://prerender.io/js-seo/angularjs-seo-get-your-site-indexed-and-to-the-top-of-the-search-results/
Mi solución: - dentro de app.js intente agregar "$ locationProvider.hashPrefix (''!'');"
.config([''$stateProvider'', ''$urlRouterProvider'', ''$httpProvider'', ''$locationProvider'',
function($stateProvider, $urlRouterProvider, $httpProvider, $locationProvider) {
$stateProvider
.state(''menu'', {
url: ''/'',
cache: false,
abstract: true,
templateUrl: ''static/www/templates/menu.html''
})
.state(''menu.main_page'', {
url: ''app/main'',
cache: false,
views: {
''menuContent'': {
templateUrl: ''static/www/templates/mainpage.html'',
controller: ''MainCtrl''
}
}
})
$locationProvider.hashPrefix(''!'');
$urlRouterProvider.otherwise(function ($injector, $location) {
var $state = $injector.get(''$state'');
$state.go(''menu.mainpage'');
});
}])
dentro de index.html intenta agregar
<meta name="fragment" content="!">
y como Marcel dijo arriba
.directive(''a'', function () {
return {
restrict: ''E'',
link: function (scope, elem, attrs) {
if (attrs.href && attrs.href.indexOf(''#'') > -1) {
elem.on(''click'', function (e) {
e.preventDefault();
});
}
}
};
})
¡eso es todo! ¡funciona para mi!
intente data-target="#something"
, funciona bien para mí tanto en el entorno de desarrollo como en el de producción.