Using angular $routeProvider with packaged apps - angularjs

I'm building a Chrome Packaged App with AngularJS and it seems highly desirable to use the $routeProvider however the methods don't seem to match the URL system inside apps.
So my question is can I implement $routeProvider functionality inside a Chrome packaged app and if so how?

Not sure if this is the best solution but I seemed to have solved this enigma myself.
Setup the $routeProvider however you want it to be and instead of using links in the application use ng-click directives that use a the $location to change the path to whatever matches up with your $routeProvider paths.
in the example below I made a "link" directive that sets the $location.path to whatever it equals when clicked.
#coffescript:
app.directive "link", ($location) ->
(scope, element, attrs) ->
element.bind "click", ->
scope.$apply $location.path(attrs.link)
app.config ($routeProvider) ->
$routeProvider
.when "",
templateUrl: "index.html"
.when "/otherPage",
templateUrl: "path/to/otherPage.html"
.otherwise
template: "Fail!"
The empty string route matches the initial state of the app.
whatever the link attr is attached to will become a clickable link.
<button link="otherPage">Take me to otherPage</button>
<div link="otherPage">Make divs clickable too why not?</div>

Related

Angular templateUrl not redirecting to MVC controller

So I am having an issue in setting up my angular routes.
Moving straight to the point, my angular routes defined don't hit my mvc controller and thus action methods.
The action method return partial views, which represent my templates.
Here is an image of my route configuration.
Here is an image of my controller actions.
I am sure I am missing something, but can't seem to figure out what.
This example helps you to understand better about $routeProvider and $locationProvider.
The only issue I see are relative links and templates not being properly loaded because of this.
from the docs regarding HTML5 mode
Be sure to check all relative links, images, scripts etc. You must either specify the url base in the head of your main html file () or you must use absolute urls (starting with /) everywhere because relative urls will be resolved to absolute urls using the initial absolute url of the document, which is often different from the root of the application.
In your case you can add a forward slash / in href attributes ($location.path does this automatically) and also to templateUrl when configuring routes. This avoids routes like example.com/tags/another and makes sure templates load properly.
Here's an example that works:
<div>
Home |
another |
tags/1
</div>
<div ng-view></div>
And
app.config(function($locationProvider, $routeProvider) {
$locationProvider.html5Mode(true);
$routeProvider
.when('/', {
templateUrl: '/partials/template1.html',
controller: 'ctrl1'
})
.when('/tags/:tagId', {
templateUrl: '/partials/template2.html',
controller: 'ctrl2'
})
.when('/another', {
templateUrl: '/partials/template1.html',
controller: 'ctrl1'
})
.otherwise({ redirectTo: '/' });
});
If using Chrome you will need to run this from a server.
Well what worked for me was to remove the setting for the $locationProvider.html5Mode. As someone mentioned in another stack overflow post, here MVC5 and Angular.js routing - URLs not matching using the locationProvider in MVC seems to screw up the routing. I am still to investigate why exactly this happens, as all I thought it did was remove the '#' in the url, but seems like there's more to it

angular routing ie9 error

In IE9 my angular routing does not work and it redirects me to whatever was before the '#' hashtag.
mysite.com/#/info -> mysite.com
even if i manually removes the /# from the URL and try again, i still get redirected.
It appends '#' to my URL because html5 mode uses History API when the browser supports it, and falls back to 'hashbang' (#) when it is not supported(like IE9).
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise("/");
$stateProvider
.state('statistics', {
url: "/path/:myId",
templateUrl: '../some/path/site.html',
controller: 'Ctrl'
}
);
been looking at various solutions such as:
AngularJS How to remove # symbol in IE9 by using route
https://gist.github.com/thomseddon/3834721
but neither of them are working for me.
I'm looking for a solution without having to deactivate html5mode. Anyone experienced similar issue and managed to fix?
In HTML5 mode, there are three situations in which the A tag is not rewritten: from the angular docs -
1 Links that contain a target attribute. Example: link
2 Absolute links that point to a different domain Example: link
3 Links starting with '/' that lead to a different base path when base is defined Example: link
You can try to use a global directive like this that add target='_self' to all all links without target.
myApp.directive('a', [function () {
return {
restrict: 'E',
link: function (scope, element, attrs) {
if (!attrs['target']) {
element.attr('target', '_self');
}
}
}
}]);

Use base domain name with $routeProvider

I am using $routeProvider with an angular app so I have a configuration like so:
$routeProvider
.when '/compilations',
templateUrl: 'angular/templates/player_compilation.html'
controller: 'compilationController'
.when '/news',
templateUrl: 'angular/templates/player_news.html'
controller: 'newsController'
.otherwise
redirectTo: '/compilations'
So this will give me the pages: www.mydomain.com/#/ compilations and www.mydomain.com/#/news
Is it possible for me to use the url: www.mydomain.com? If so, what would be the configuration?
Additional Explication
What I am trying to do (and perhaps this is a lost cause) is use angularjs for only part of the domain. so www.mydomain.com/news, and www.mydomain.com/compilations are part of the angular app, but www.mydomain.com/sign_in gets served separate, non-angular content. So this works, but I am trying to get the base domain: www.mydomain.com to be part of the angular app without a redirect. I have been unable to figure out how to do this?
I solved this by using $location html5 modes. For pages outside the angular app I created a controller which reloaded the page:
.otherwise
templateUrl: 'angular/templates/blank_page.html'
controller: 'redirectController'

Angularjs - how to clear $routeProvider's caches of templateUrl

I have really basic use case in my app where I use AngularJS (1.0.8) for front end and Grails for back end. In the app layout I have a language switcher which allows the user to change the language. Switching the language, it does new http request to retrieve the page. Grails renders all language related stuff (i.e. labels) properly translated. This only works for Chrome, FF, and so but not for IE. IE renders proper language just for layout which is rendered by the main request.
I located the problem. I have defined $routeProvider where I load major of the app content. It is cached by default, therefore IE doesn't load templateUrl of $routeProvider because it loads them from cache:
myApp.config(function ($routeProvider) {
$routeProvider.
when('/', {controller: 'MyCtrl', templateUrl: '/eshop/myConfig'})
});
What I don't get is why it works in all other browsers.
I found some post how to clear cache but they doesn't work for me. Is there any solution for me? If not, I find $routeProvider completely useless for my use case.
Post I found:
angularjs clear history when view loaded
AngularJS disable partial caching on dev machine
Below should do it. You can manipulate angularjs's template caches by using $templateCache, so $routeProvider will load the template as new every time you access the controller.
myApp.config(function ($routeProvider) {
$routeProvider.
when('/', {controller: 'MyCtrl', templateUrl: '/eshop/myConfig'})
})
.controller('MyCtrl', function ($scope, $templateCache) {
$templateCache.remove('/eshop/myConfig');
// or
$templateCache.removeAll();
});
I was having the same issue with $routeProvider. And yes, the $templateCache does not help in this situation. Instead of keeping finding the real 'cache' source, I added the stamp parameter after the templateUrl.
In my code:
$routeProvider.
when('/', {templateUrl: '../views/home.html?v='+window.buildNumber, controller: 'HomeCtrll'}).
when('/report', {templateUrl: '../views/form.html?v='+window.buildNumber, controller: 'FormCtrll'}).
otherwise({redirectTo: '/'});
Sadly, I used a global variable "buildNumber" to save my life. Because I also use RequireJS for my AngularJS project, so this "buildNumber" will also be added to every dependency JS file by using the code:
require.config({
urlArgs: "v=" + window.buildNumber,
paths: {....}
});
Then every time the JS source or template html has been changed, I will only need to update that "buildNumber" in global scope. This is just a thought for the future updates in production environment. Hope this helps.
So the only solution I found was to completely disable cache for ajax queries. I found the solution here: https://stackoverflow.com/a/19771501/607038
myModule.config(['$httpProvider', function($httpProvider) {
//initialize get if not there
if (!$httpProvider.defaults.headers.get) {
$httpProvider.defaults.headers.get = {};
}
//disable IE ajax request caching
$httpProvider.defaults.headers.get['If-Modified-Since'] = '0';
}]);
I don't like this solution because it disable cashing for the content which is really static. So if you have better solution than share it.

AngularJS render html as string

In my web app, when I go to one of my url, angularjs returns me haml template as a plain text.
But if I go to my root url it works fine. I use Rails 3.2.13, AngularJS 1.1.4, Haml for views.
This is my app/views/layouts/application.html.haml
!!! 5
%html{'ng-app' => 'myproject'}
%head
%title MyProject
= favicon_link_tag
= stylesheet_link_tag 'application'
= javascript_include_tag 'application'
= csrf_meta_tag
%body
.main-background
.app{'ng-view' => ''}
= yield
This is my app/assets/javascripts/main.js.coffee
#app = angular.module('myproject', [])
This is my app/assets/javascripts/routes.js.coffee
app.config ['$routeProvider', '$locationProvider', ($routeProvider, $locationProvider) ->
$routeProvider
.when '/',
templateUrl: '/assets/signin/index.haml',
controller: 'SignInController'
.when '/signup/:code',
templateUrl: '/assets/signup/index.haml',
controller: 'SignUpController',
]
I have 2 controllers in app/asssets/javascripts/controllers/ respectively. They both are emty.
I also use html5 push state, lik this(push_state.js.coffee)
app.config ($locationProvider) ->
$locationProvider.html5Mode true
And, I have views, in app/assets/templates, whith path, that I wrote in templateUrl.
My problem is, when I go to '/', angularjs render my view fine, but, when I go to the second url, it returns me a plain text in span tag, with haml template inside it. I tried to use only one when statement with the second template and it was the same result.
And, the question is what should I do to render my second view properly ?
I found a solution. It strange, but when I do some edit in my templates, and revert then back, after that all templates render properly. In both cases, before edit and after, templates have the same markup.

Resources