How to prevent $location adding forward slash to hash url

3,187 views
Skip to first unread message

Søren Kyndi-Wiuff

unread,
Jul 18, 2013, 5:17:30 AM7/18/13
to ang...@googlegroups.com
The problem
I have an large non-angular site with an URL structure like so:


The non-angular site uses the hash part of the URL for it's own state.

In this site I am trying to use Angular 1.0.7 for some small widgets - a perfect match, right? :)

The problem is that when I start my widget (Angular App) it changes my URL and thus the state of the non-angular site.

It adds a forward slash to the hash part of the url, like so:


By doing that, the state of the non-angular site is destroyed causing all kinds of errors.

Any ideas on how to force AngularJS to keep it's hands off my hash? ;)

The setup

The site have loaded a javascript file that defines my App. Along these lines:

var App = angular.module("MyApp", []).controller("MyCtrl", function() { ... });

Then I create a dom element along these lines:

var el = document.createElement("DIV");
el.setAttribute("ng-controller", "MyCtrl");
el.setAttribute("ng-include", "'/path/to/my/template'");
document.appendChild(el);
angular.bootstrap(el, ["MyApp"]);

fess

unread,
Jul 18, 2013, 2:07:51 PM7/18/13
to ang...@googlegroups.com

This may not be practical, but I believe if you never inject $location (or $route) then angular will leave your hash alone.

if that is correct and you need $location you might make a modified version and override the ng one. ??

Søren Kyndi-Wiuff

unread,
Jul 19, 2013, 2:21:13 AM7/19/13
to ang...@googlegroups.com
Looking through the code I don't use $location or $route (or any of the providers for those two).

Checking Angular source, it doesn't seem like I use a service that depends on those either.

Is there something I am missing with those dependencies perhaps? :)

Søren Kyndi-Wiuff

unread,
Jul 19, 2013, 5:18:55 AM7/19/13
to ang...@googlegroups.com
I have dug a bit deeper and now think I know what the problem at hand is.

fess, you mentioned it could be due to $location being loaded -and that is the case.

Remember how I mentioned doing this: 
el.setAttribute("ng-include", "'/path/to/my/template'");


Turns out that ngInclude depends on $autoScroll - which in turn depends on $location. So, there you have it! :)

The solution would be to find a way to load a partial without using ngInclude. 

Søren Kyndi-Wiuff

unread,
Jul 19, 2013, 7:00:27 AM7/19/13
to ang...@googlegroups.com
Just for completeness sake, here is the final solution which bootstraps a widget without using $location in any way. All that is needed is, that 'view.html' declares it's own elements with an ng-controller attribute.

function load() {
var element = document.createElement("DIV");
document.body.appendChild(element);
var mod = angular.module('App');
mod.constant('data', { time : new Date().toISOString() });
angular.injector(['ng']).invoke(['$http', function($http) {
$http.get('view.html').success(function(html) {
angular.element(element).html(html);
angular.bootstrap(element, ['App']);
});
}]);




Reply all
Reply to author
Forward
0 new messages