Angular routing without changing location - javascript

Chrome Packaged Apps have a rather strict Content Security Policy. One result of this is that manipulating the location (like clicking on a link) results in:
'Can't open same-window link to "chrome-extension://lkjasdfjklbdskjasdfjkhfdshjksad/derp.html"; try target="_blank". '
Target _blank will open the link in chrome which is not what I want. Can AngularJS' routing work in such a locked-down environment?
They docs give an example of an Angular app, but conspicuously does not use routing.
Update
Here is the link that, when clicked, gives the error: <a class='walrus-link' ng-href='paystubs/{{walrus.id}}'>Walrus {{id}}!</a>

Instead of using an href, try using ng-click and call a method to your controller the relocates to the appropriate page using $location. See the documentation on the AngularJS site. The following quote from the doc gives an indication that the $location service might be appropriate for you:
When should I use $location? Any time your application needs to react
to a change in the current URL or if you want to change the current
URL in the browser.
Your code might look something like this:
<a class='walrus-link' ng-click='getPaystub(walrus.id)'>Walrus {{id}}!</a>
and in your parent controller, you'll need a scope method called 'getPaystub' with a line similar to:
$scope.getPaystub = function(selectedWalrusId) {
$location.path('paystubs/'+$scope.walrus.id);
}
This way angular keeps control and won't cause a page refresh. This hopefully keeps you within the bounds of the CSP. Unfortunately I cannot test this in a packaged app, but I've used the exact same convention in a web app and it works just dandy.

routing works for me in my chrome app when not using $routeProvider's html5 mode (which is disabled by default), you just have to use a hash in the url.
so my links look like this:
About
$routeProvider configuration is as follows:
$routeProvider.when('/about', {templateUrl:'about.html'})

Related

angular parses url with LocationHashbangUrl but $locationProvider.html5Mode(true) is set

I encounter a strange behaviour with angular and html5Mode:
When i enter an url of the SPA i can see in the debugger that initally the LocationMode is LocationHashbangUrl even though $locationProvider.html5Mode(true) is set.
So the Url is first parsed by LocationHashbangUrl.
Then after angular has executed $locationProvider.html5Mode(true) the url gets parsed again.
I compared this to a rather simple example implementation from this http://plnkr.co/edit/DA3Oq6?p=info there it is not the case and angular starts with LocationHtml5Url right away.
I suspect that this causes troubles with the browser back button.
When i use the backbutton of the browser i can see in the debugger that the url is first parsed again by LocationHashbangUrl instead of LocationHtml5Url and this causes a Url change to an empty path.
I use angular 1.2.28 and angular-route 1.2.28 in a requirejs context.
Btw this is a followup of angular routes are in history but browser back jumps to first entered url
I found the reason:
There was a module bootstrapped before the actual main application and this was the reason for the inital LocationHashbangUrl object.
Setting $locationProvider.html5Mode(true); in this module as well solved it.

What is the difference between window.location and $location.path?

In MVC angularJS application, how can I redirect to MVC page.
I tried below two options
First
// It doesn't work
$location.path("/MyPage1");
Second
//It works
window.location = "/MyPage1";
Please suggest best way to redirect and why ?
REMEMBER : I am not using angularJs Routing.
Comparing $location to window.location official doc clearly stated
see the section at this location
seamless integration with HTML5 API
window.location: no
$location: yes (with a fallback for legacy browsers)
and more
Both do have their own merits. They are clearly described in the official docs as mentioned by #Mohammad. So depending on the circumstances choose any of the either :
Use $location : When you do not require a full page reload when the browser URL is changed, wants to avail the angular internal life-cycle benefits and where you don't need to support old legacy browsers.This might be useful if your destination is just a variation on the current URL, so that you can take advantage of $location helper methods. E.g. we ran $location.search(..., ...) to just change value of a querystring paramater.
Use native window location : When you need to change the URL and reload the page or navigate to a different page, please use a lower level API: window.location.href or when you want to work with row level object properties that you can directly modified. i.e like Force reload window.location.reload().

History mode in angularjs

I am using angularjs with history mode turned on and would want to make all links(all a's href) to load with history api... So, i have set
$locationProvider.html5Mode(true)
And now the issue is that all pages reload the normal way. The url set in base tag is
http://localhost:8080/laravel/public/
Got it solved... So, i would have to do the routing. I had to add routes to load with history api...

Cannot route to a url with a different protocol with angularjs

I am trying to open an application client side and I have developed this entire application using only angularjs as a front end. It seems to be hijacking the routing and disallowing this.
In old javascript I used to be able to do
var wnd = window.open("dynamicsnav://arbitraryLinkDetails", "_blank");
wnd.close(); // this opens the protocol to start the application client
// side and closes the extra browser window
to open the Nav application client side and the details of what to open in place of arbitraryLinkDetails.
Now when I do this inside of my angular app it appends localhost to the url(really it is the base domain it attaches) like this
"http://localhost/"dynamicsnav://arbitraryLinkDetails""
which does not work.
Things I have tried
appending "//" to the url to break out of the angularjs routing, this tacks on a %22 to the beginning and removed the : for the protocol like "%22dynamicsnav//arbitraryLinkDetails"
I have tried modifying the routing so
var redirectFunction(){
return theUrl; //this gets the full url of dynamicsnav://arbitraryLinkDetails
}
$routeProvider
.when('/NavUrl', {redirectTo: redirectFunction})
and that again appended base url to it.
This is a requirement for my current project and I simply cannot figure out a way to open this like I used to with angularjs.
I verified the url's I am testing with work in another application not using angular. Thanks for any help!
The AngularJS $routeProvider service manage routes that deep link controllers with views, wich is not your case, why don't you try this :
var redirectFunction(){
window.open("dynamicsnav://arbitraryLinkDetails", "_blank");
}
$routeProvider
.when('/NavUrl', {redirectTo: redirectFunction})

Force reload of a directive's template

I am working on an AngularJS app with several directives. The directive's templates are stored in a separate html file. When editing these template, my browser does not detect any changes after a reload and always uses a cached version. Any other changes to the source code are detected and lead to a reload.
I guess the problem is somewhat the $templateCache which seems to be used by AngularJS when loading the template.
What I found in the source code of AngularJS 1.0.2 is the following from line 4317 which is part of the compileTemplateUrl():
$http.get(origAsyncDirective.templateUrl, {cache: $templateCache})
I am wondering if anyone else had this kind of problem and if there is a way to tell AngularJS when to cache and when not.
I know this is an old question, but here's a simpler fix, although it's a bit of a hack, it works for me, and doesn't require you to do anything to $templateCache.
Whenever I run into this problem (I see it in directive templates, but also static JSON files), I add a query parameter to the end of the URL being loaded, like this:
...
templateUrl: "partials/template.html?1",
...
Whenever I make a changes to the template, and it's not reloading, I increment that number at the end. As the browser doesn't know if this might mean something special to the server, it should attempt to reload that changed URL whether it's cached or not. This will also make sure the file is reloaded in the production environment.
The template cache is stored in your browser, as this is a javascript app. You can actually feed the $cache manually or stop your browser from caching the templates (as it would seem that for production, cache won't be a problem), using developer tools.
For force feeding the cache:
function Main($cache) {
$cache.data['first.html'] = {value: 'First template'};
$cache.data['second.html'] = {value: '<b>Second</b> template'};
}
Main.$inject = ['$xhr.cache'];​
See it working in this fiddle.
To stop your browser from caching the templates (cited from this Google Groups post, about this problem, exactly):
My team and I have ran into this same issue. Our solution for
development while using Chrome was to open Developer Tools, and select
the gear in the bottom right hand corner. Then select Network -
Disable cache.
This fixed all our partial/template caching issues.
app.controller('someCtrl', function ($scope, $cacheFactory, templateRequest)
{
$scope.refreshTemplate = function ()
{
var tpl = "<template name>";
$cacheFactory.get('templates').remove(tpl);
$templateRequest(tpl).then(function ok(){
console.log("Template "+tpl+" loaded.");
});
}
...
}
then when you call the refreshTemplate function you cause a re-load

Categories

Resources