2016-06-20 10 views
11

Wir haben ein Projekt, das Angular verwendet, aber nur für den UI-Bindungs-/AJAX-Aspekt, nicht für irgendeine Art von Routing- oder SPA-Funktionalität.Entfernen Sie das Hashchange-Ereignis von Angular oder verhindern Sie, dass Angular die Ankerlinks umschreibt

Wir wollen in der Lage sein, Anker-Links zu verwenden (#section-2) in Artikeln, die wir innerhalb des CMS schreiben wir gewählt haben, sowie die Nutzung Anker Links von anderen Seiten (/my-page#section-C), aber Angular umschreibt dieser #/section-2, die das brechen Anker-Links, die der CMS einrichtet.

Es ist nicht möglich, den CMS zu erweitern, um zu ändern, wie Ankerverbindungen behandelt werden.

Ist es möglich, entweder:

  1. das hashchange Ereignis entfernen aus Angular Bindung? Ich sehe, dass dieses Ereignis in der Quelldatei src/ng/browser.js angefügt ist, wo es einige der Routing-und Link Neuschreiben behandelt, aber es ist innerhalb einer Schließung, so dass nicht direkt zugegriffen werden kann (und wir sind Angular von einem CDN verknüpfen, so ist es nicht möglich, die Angular-Quelle zu modifizieren, und wir wollen nicht unsere eigene "benutzerdefinierte" Angular-Quelle beibehalten.

  2. Legen Sie eine Option fest oder rufen Sie eine Konfigurationsmethode auf, die letztendlich den gesamten Routing-Aspekt von Angular deaktiviert und verhindert, dass irgendwelche Links neu geschrieben werden? (Oder ist es eine Möglichkeit, nicht diesen Teil von Angular zu umfassen, aber immer noch den Controller/UI Bindung/AJAX-Funktionalität beibehalten?)

Bitte beachte, dass ich bereits versucht haben, dieses:

$locationProvider.html5Mode(true) 

Es macht jedoch alle anderen Links auf der Website funktionsunfähig, da alle Links zur Verarbeitung durch Angular übergeben werden. Also wenn ich auf die Homepage verlinke (<a href="/">Home</a>) und auf den Link mit klicke, macht der Link nichts.

+0

Ich verwende Angular in ASP.NET-Projekt nur für UI-Bindung, keine Setup keine Routen und nicht ngRoute Modul verwenden. Alle Links funktionieren korrekt – Mikalai

+0

@Mikalai Ich verwende kein Routing, noch verwende ich ngRoute. Alles, was ich getan habe, ist "angular.min.js" in meine Site aufzunehmen, und ich versuche, Anchor-Links zu verwenden, und Angluar schreibt sie neu. – qJake

Antwort

2

Als eine Art Workaround (und sicherlich nicht als Best Practice), habe ich die Angular-Quelle modifiziert, um das URL-Rewriting zu entfernen.

machte ich ein paar Änderungen, aber ich glaube, derjenige, die Ankerverbindungen verursacht, wieder zu arbeiten auf der Linie 844 von location.js in der Winkelquelle eine return; Erklärung wurde hinzugefügt:

https://github.com/angular/angular.js/blob/master/src/ng/location.js#L844

Diese Kurzschlüsse um einen Großteil der URL-Neuschreibfunktion.

ich auch vollständig entfernt Linien 262-264 von browser.js, die auf dem hashchange Ereignis Angular der Haken entfernt:

https://github.com/angular/angular.js/blob/master/src/ng/browser.js#L262-264

Dies nicht der Bindungseigenschaften von Angular zu beeinflussen schien, aber es hat dazu geführt, dass Ankerlinks wieder funktionieren.

3

Ich glaube, dass Sie wollen $anchorScroll. Siehe diese verwandte Antwort: How to handle anchor hash linking in AngularJS

Hier ist ein Beispiel dafür, wie es funktionieren würde. Der Hash wird nur als Teil der ID behandelt:

app.controller('TestCtrl', function($location, $anchorScroll) { 
    var vm = this; 
    vm.scrollTo = function(id) { 
     $location.hash(id); 
     $anchorScroll(); 
    } 
}); 

<a ng-click="vm.scrollTo('#foo')">Foo</a> 

<div id="#foo">Here you are</div> 

plunker demonstrating $anchorScroll Siehe

Mit Routing, können Sie den Link ändern:

<a href="#/test##foo">Test/Foo</a> 

und fügen Sie diese Konfiguration auf der Flucht:

$rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) { 
    if($location.hash()) { 
     $anchorScroll(); 
    } 
}); 

Siehe plunker demonstrating scrolling with routing and $anchorScroll

+0

Das Problem damit (und der Grund, warum es nicht funktioniert) ist, dass das CMS, mit dem wir integriert haben, nur Anker-Links in der traditionellen HTML-Art erzeugt. Ihr Beispiel ('Foo') funktioniert nicht, da der WYSIWYG-Editor des CMS keine Ankerlinks auf diese Weise erzeugen kann. ** Das Anker-Link-Format darf sich nicht ändern. ** – qJake

+0

Und tatsächlich habe ich in '$ routeChangeStarted',' $ routeChangeSuccess' und '$ routeChangeError' gehakt, und keines dieser Ereignisse wurde von meinem Controller ausgelöst diese Seite. Ich habe '$ rootScope' als Abhängigkeit, die in meinen Controller gezogen wird. – qJake

+0

Sofern Sie nicht ngRoute verwenden, haken Sie in die [$ location events] (https://docs.angularjs.org/api/ng/service/$location) –

-2

Aber warum nicht ng-Route verwenden? Es würde Ihre Probleme vollständig lösen. Mit Ng Routen können Sie folgendes erreichen (was Sie wollen).

<a href="http://www.example.com/base/#section-A"> Section A</a> 

<a href="http://www.example.com/base/my-page#section-C">Another page</a> 

<a href="/other-base/another?search">external</a> 

hier ist die app.js

Snippet
app.config(function($locationProvider) { 
    $locationProvider.html5Mode(true).hashPrefix('!'); 
}) 

Html Link Umschreiben

Wenn Sie HTML5 Geschichte API-Modus verwenden, benötigen Sie spezielle Hash-Bang Links nicht benötigen. regelmäßige URL-Links, wie angeben Alles, was Sie tun müssen, ist: <a href="/some?foo=bar">link</a>

Wenn ein Benutzer klickt auf diesen Link,

In einem Legacy-Browser die URL Änderungen an /index.html#!/some?foo=bar

In einem modernen Browser, Die URL ändert sich in /some?foo=bar

In Fällen wie dem Folgenden werden Verknüpfungen nicht umgeschrieben; Stattdessen lädt der Browser die gesamte Seite neu auf den ursprünglichen Link.

Links, das Zielelement Beispiel enthalten: <a href="/ext/link?a=b" target="_self">link</a>

Absolute Links, die Beispiel zu einem anderen Domäne gehen: <a href="http://angularjs.org/">link</a>

Verbindungen mit '/' beginnend Beispiel zu einem anderen Basispfad führen: <a href="/not-my-base/link">link</a>

Relative Links

Achten Sie darauf, alle relativen zu überprüfen Links, Bilder, Skripte etc. Angular erfordert, dass Sie die URL-Basis im Kopf Ihrer Haupt-HTML-Datei angeben (<base href="/my-base/index.html">), es sei denn, html5Mode.requireBase ist im html5Mode-Definitionsobjekt auf $ locationProvider.html5Mode() auf false gesetzt. Damit werden relative URLs immer in diese Basis-URL aufgelöst, auch wenn die ursprüngliche URL des Dokuments anders ist.

Es gibt eine Ausnahme: Links, die nur ein Hash-Fragment enthalten (z. B. <a href="#target">), ändern nur $ location.hash() und ändern die URL sonst nicht. Dies ist nützlich, wenn Sie zu Anchors auf derselben Seite scrollen möchten, ohne wissen zu müssen, auf welcher Seite sich der Benutzer gerade befindet.

Server-Seite

diesen Modus erfordert auf Server-Seite URL-Rewriting, im Grunde Sie alle Ihre Links zum Eintrittspunkt der Anwendung neu zu schreiben haben (zum Beispiel index.html). Das Erzwingen eines Tags ist auch in diesem Fall wichtig, da Angular zwischen dem Teil der URL, der die Anwendungsbasis darstellt, und dem Pfad, der von der Anwendung behandelt werden soll, unterscheidet.

ngSource

0

Nach der Einstellung $ locationProvider.html5Mode (true), haben Sie auch eine <base> im <head> des Dokuments festgelegt?

<html> 
    <head> 
    <base href="/"> 
    </head> 
</html> 

Werfen Sie einen Blick here:

„Es gibt zwei Dinge, die getan werden müssen, um

  1. Konfigurieren von $ locationProvider
  2. Einstellung unserer Basis für relative Links
.

oder here

+0

Ja, ich hatte ein '', das hindert Angular nicht daran, das Verhalten aller '' Tags auf der Site neu zu schreiben.Wie ich bereits sagte, würde das Klicken auf einen Standardlink im CMS, zum Beispiel "Home", durch Angular routen, für das Angular keine Route hatte, also würde nichts passieren, wenn Sie auf den Link klicken. – qJake

0

Ich hatte ein ähnliches Problem bei der Verwendung von eckig mit WordPress und fand eine wirklich einfache Lösung. Alles, was Sie tun müssen, ist alle $ location injection in Ihren Controllern zu entfernen. Wenn Sie $ location service injizieren (ob Sie es verwenden oder nicht), entführt es das # Verhalten.

Das bedeutet, dass Sie alle Ihre Controller, Direktiven usw. durchforsten müssen und sicherstellen, dass der $ location Service nirgends eingefügt wird.

HTH

1

Angular der $locationProvider.html5Mode function with it's rewriteLinks Einstellung ist das, was Sie suchen. Es wird eckig in einen Modus gesetzt, in dem $ location immer noch verwendet werden kann, um die URL des Browsers zu lesen und zu schreiben, aber es wird niemals versuchen, Linkklicks zu entführen und angulares SPA-Routing auszulösen.

zB:

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

Ich habe diese Option nicht gesehen, als ich in der Dokumentation nachgesehen habe. Es ist möglich, dass wir eine ältere Version von Angular verwenden, die diese Option nicht enthält. Du hättest das beantworten sollen, wenn das Kopfgeld aktiv war! :) – qJake

+0

@qJake Haha, ich hatte dieses Problem gerade erst letzte Nacht. War im Begriff, den gleichen Weg wie Sie zu gehen (Bearbeiten der Winkelquelle), fand aber eine weitere SO-Antwort, die mich auf diese Dokumente zeigte. Sehr versteckt, nichts anderes verweist es abgesehen von diesem 1 kleinen Kommentar innerhalb der html5mode-Methode. Es ist anscheinend seit 1.3 dort gewesen, aber ich habe auch nie davon gewusst. – Tyson

+0

@qJake Du kannst die akzeptierte Antwort immer auf meine ändern;) – Tyson