it-swarm.com.de

So verhindern Sie die Umleitung von <a href="#something"> in Angular Js1.2

Ich habe in meiner Anwendung AngularJs-1.0.7 und Bootstrap verwendet. Vor kurzem bin ich von AngularJs-1.0.7 zu AngularJs-1.2 gewechselt. Ich benutze Bootstraps Akkordeons und Tabs.

Der HTML-Code für Tab enthält wie unten gezeigt <a href="#id_for_content">.

<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>

In den alten Versionen von Angular findet die Routenänderung nur statt, wenn wir ein Ankertag wie <a href="#/firstTab"> angeben. Aber AngularJs-1.2 leitet <a href="#firstTab"> um. Es berücksichtigt nicht den / zwischen # und firstTab. Während Sie also auf Tab klicken, wird auf http://web_url/#/firstTab weitergeleitet. Wie löse ich dieses Problem?


Meine Lösung

Ich habe eine Lösung für dieses Problem gefunden. Ich habe eine Direktive für ein Tag geschrieben. In dieser Direktive habe ich nach dem Attribut "href" gesucht. Wenn es übereinstimmt, verhindern Sie das Standardverhalten. Überprüfen Sie den folgenden Code.

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();
                });
            }
        }
   };
}); 

Das Problem bei dieser Methode ist jedoch, dass ich hier jede Tab-ID oder Akkordeon-ID überprüfen muss. Wenn ich für sie dynamische IDs verwende, ist das Einchecken von Direktiven nicht möglich. 

Wenn Sie eine bessere Lösung finden, lassen Sie uns alle davon wissen.

23
Sajith

Fügen Sie dies einfach zu Ihren Links hinzu:

target="_self"

Und du bist bereit;)

46
Vassilis Pits

versuchen Sie data-target="#something", es funktioniert für mich sowohl in der Entwicklungs- als auch in der Produktionsumgebung.

19
Sonymon Mishra

Ich möchte Sie nur wissen lassen, dass es eine andere Lösung gibt, um dieses Problem zu lösen (ohne die Funktion in Controllern zu definieren).

Sie können eine Direktive erstellen, die das Verhalten des Standardbrowsers verhindert (wodurch die URL tatsächlich geändert wird):

var PreventDefault = function () {

    var linkFn = function (scope, element, attrs) {
        $(element).on("click", function (event){
            event.preventDefault();
        });
    };

    return {
        restrict: 'A',
        link: linkFn
    }
};

und fügen Sie einfach die Direktive zu jedem a-Element hinzu, das für das Umschalten eines Registers wie folgt verantwortlich ist:

<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>
10
PrimosK

Im Allgemeinen können Sie Funktionen des Prototyps aller Bereiche mithilfe des Wurzelbereichs definieren. Klicken Sie auf Ihre Ankertags und klicken Sie auf übergeben Sie das $ -Ereignis an die Rootscope-Handler. Angular kann das Ursprungsereignis auch mit ng-click senden:

<a ng-click="tabclick($event)">

in einem Laufblock Ihres Moduls können Sie dann eine TabClick-Funktion auf $ rootScope setzen

$rootScope.tabclick = function ($event) { $event.preventDefault(); }

Dies funktioniert für alle Bereiche und Sie müssen nicht nach bestimmten Element-IDs suchen.

Beispiel-Geige: http://jsfiddle.net/stto3703/wQe6P/

Prost

6
Stefan

Sie können mit ng-click eine Funktion in Ihrem JS aufrufen. Verwenden Sie in dieser Funktion die preventDefault-Methode des Ereignisses und verwenden Sie die hash-Methode von $location, um den Hash in Ihrer URL zu ändern. 

2
yarons

Ich habe dieses Problem nun auch schon eine Weile und bin nur über diese Frage (und Ihre eigene Antwort) gestolpert. Es stellt sich heraus, dass Sie mit Ihrer Lösung beinahe korrekt sind. Nur eine geringfügige Änderung macht es möglich, wie Sie möchten.

Neben dem Problem, das Sie mit Registerkarten hatten, bin ich auch mit Dropdown-Links auf dieses Problem gestoßen - sie navigierten beim Anklicken von der aktuellen Seite, anstatt das Menü herunterzulassen - und tatsächlich ist dieses Problem vorhanden jeder Link, der entworfen wurde, um etwas umzuschalten, dh mit dem Attribut Data-Toggle.

Eine geringfügige Änderung Ihres Codes, um zu prüfen, ob das Attribut 'toggle' vorhanden ist, löst es für mich:

app.directive('a', function() {
    return {
        restrict: 'E',
        link: function(scope, elem, attrs) {
            if(attrs.toggle){
                elem.on('click', function(e){
                    e.preventDefault();
                });
            }
        }
   };
});

Hoffe das hilft!

1
Tom Spink

Wenn Sie mit den vorherigen Antworten keinen Erfolg haben, können Sie $ timeout verwenden. In diesem Fall habe ich AngularUI-Registerkarten verwendet.

vm.removeUserTab = function (user) {
    $timeout(function () {
        vm.activeTab = 0;
        var index = vm.userTabs.indexOf(user);
        vm.userTabs.splice(index, 1);
    });
};
0
soreal

kredite an https://prerender.io/js-seo/angularjs-seo-get-ihr-site-index-und-auf-der-der-der-der-der-forschungsergebnisse/

Meine Lösung: - In app.js versuchen Sie, "$ locationProvider.hashPrefix ('!');" hinzuzufügen.

    .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');
    });
   }])
  • inside index.html versuche das Hinzufügen 

    <meta name="fragment" content="!">

und wie Marcel oben gesagt wurde

.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();
            });
        }
    }
};
})

das ist alles! funktioniert bei mir!

0

Ihre Lösung in Ihrer Frage funktioniert zwar, aber ändern Sie nicht die ID jedes Ankers 

if (attrs.href === '#firstTab'|| attrs.href === '#secondTab')

zu

if (attrs.href && attrs.href.indexOf('#') > -1)

Richtlinie:

.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();
                });
            }
        }
    };
})  
0
Marcel