We have a project which uses Angular, but only for the UI binding/AJAX aspect of it, not for any sort of routing or SPA functionality.
We want to be able to use anchor links (#section-2
) in articles we write within the CMS we have chosen, as well as use anchor links from other pages (/my-page#section-C
), but Angular rewrites these to #/section-2
, which breaks the anchor links that the CMS sets up.
It is not possible to augment the CMS to modify how anchor links are handled.
Is it possible to either:
Remove the hashchange
event binding from within Angular? I see that this event is attached to in the source file src/ng/browser.js
where it handles some of the routing and link rewriting, but it's inside of a closure so it cannot be accessed directly (and we are linking to Angular from a CDN so it is not possible to modify the Angular source, plus we don't want to have to maintain our own "custom" Angular source).
Set an option or call a configuration method which ultimately disables the entire routing aspect of Angular and prevents it from rewriting any sort of links? (Or, is there a way to not include this portion of Angular, but still retain the controller/UI binding/AJAX functionality?)
Note that I have already tried this:
$locationProvider.html5Mode(true)
However it renders all other links on the site inoperable because all links are passed through Angular for processing. So if I link to the homepage (<a href="/">Home</a>
) and click the link with html5mode
on, the link does nothing.
I believe that you want $anchorScroll. See this related answer: How to handle anchor hash linking in AngularJS
Here is an example of how it would work. The hash is just treated as part of the id:
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>
See plunker demonstrating $anchorScroll
With routing, you can change the link to:
<a href="#/test##foo">Test/Foo</a>
and add this to the run configuration:
$rootScope.$on('$routeChangeSuccess', function(newRoute, oldRoute) {
if($location.hash()) {
$anchorScroll();
}
});
See plunker demonstrating scrolling with routing and $anchorScroll
As somewhat of a workaround (and certainly not best practice), I ended up modifying the Angular source in order to remove the URL rewriting.
I made a few changes, but I believe the one that caused anchor links to work again was adding a return;
statement on Line 844 of location.js
in the Angular source:
https://github.com/angular/angular.js/blob/master/src/ng/location.js#L844
This short-circuits around much of the URL rewriting functionality.
I also completely removed Lines 262-264 of browser.js
, which removes Angular's hook on the hashchange
event:
https://github.com/angular/angular.js/blob/master/src/ng/browser.js#L262-264
This didn't seem to affect any of the binding features of Angular, but it did cause anchor links to start working again.
Angular's $locationProvider.html5Mode function with it's rewriteLinks
setting is what you're looking for. It will put angular into a mode where $location can still be used to read and write the browser's url, but it won't ever attempt to hijack link clicks and trigger angular's SPA routing.
eg:
$locationProvider.html5Mode({
enabled: true,
requireBase: false,
rewriteLinks: false
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With