I want to use $routeProvider for loading the partials from the server, but I don't want the url # value changes and the history changes ( App should go back to previous url without multiple back button clicks after multiple route changes within my app )
I don't think this is possible. As far as I know $routeProvider needs those Url changes.
Another way to do this would be to use ng-show and ng-hide to display partials on the page without changing the url. You can load the partials from the server using $http or $resource and if it needs it, use the $compile to execute any angular in those partials (ie directives).
Related
I want to watch a location and run a function when the location changes.
I also want to be able to easily change locations by running a function.
I want to be able to use the browser back buttons.
Sound like a good mission for ngRoute or ui-router
No.
I don't need views, templates, and controller.
I want the power of ui-router and ngRoute for parsing URL's and get the stateParams.
In other words: How to use routes in angular without using views, templates, or controllers?
Sounds what you need is just the $location service. You can use it without ngRoute or ui-route.
The $location Service. What does it do?
The $location service parses the URL in the browser address bar (based on window.location) and makes the URL available to your application. Changes to the URL in the address bar are reflected into the $location service and changes to $location are reflected into the browser address bar.
The $location service:
Exposes the current URL in the browser address bar, so you can
Watch and observe the URL.
Change the URL.
Maintains synchronization between itself and the browser's URL when the user
Changes the address in the browser's address bar.
Clicks the back or forward button in the browser (or clicks a History link).
Clicks on a link in the page.
Represents the URL object as a set of methods (protocol, host, port, path, search, hash).
-- AngularJS Developer Guide -- Using $location
Events
$locationChangeStart
Broadcasted before a URL will change.
$locationChangeSuccess
Broadcasted after a URL was changed.
-- AngularJS $location Service API Reference
You can use the $location service without either the Angular router or the Angular-UI router. In fact you can use it if you want to roll your own router.
I am not sure what is your setup is, but if you control all the routes and they are rather limited, then you can try to add the "abstract" states, they don't need a view or a controller. I think that by the way this is not required for ordinary states either, but not 100% sure.
Perhaps if you define the abstract route for the top of your application, then you will get events for all "theoretical" children.
You can find an example of abstract state here
$stateProvider
.state('contacts', {
abstract: true,
url: '/contacts',
})
Now if you will go to /contacts you should get the event of stateChange, and I think you will get it if you will go to /contacts/something as well. In the worst case you might define you whole application as a tree of this parent/child states that are all abstract.
To handle the event you need to do this:
$rootScope.$on('$stateChangeStart', function(event, toState){
var greeting = toState.data.customData1 + " " + toState.data.customData2;
console.log(greeting);
On one page I load content via ajax according to user picks (filters), to ensure that loaded content stays in place if user reloads or lands on the page, I put the picked filters into the url query string. Since I load the content via ajax on this particular page I don't need to reload the entire page every time a new filter is picked by the user, so I prevent browser to react on url change with the following config:
app.config(['$locationProvider', function($locationProvider) {
$locationProvider.html5Mode(true);
}]);
However this affects the entire app and prevents all other pages from reloading on url change, the behavior I don't want. How can I make this configuration to affect only one particular controller within my app?
If your goal is to prevent reloading the page when the query string changes, html5Mode is entirely the wrong tool for the job. You want reloadOnSearch: false which can be applied globally or to individual routes:
$routeProvider
.when('/foo', {
controller: 'fooCtrl',
templateUrl: 'foo.html',
reloadOnSearch: false
},
...
);
https://docs.angularjs.org/api/ngRoute/provider/$routeProvider
From Angular's documentation on $locationProvider, maybe the cause of that behavior is by design:
rewriteLinks - {boolean} - (default: true) When html5Mode is enabled,
enables/disables url rewriting for relative links.
If your app is reacting to the url to make a change as a sort of RESTful api I would recommend using ngRoute or even better uiRouter.
Hope that helps.
This is a tricky situation, and you might not like my suggestion; heck I don't even like this suggestion because it breaks the whole awesomeness of a single page application.
But what you could do, is to create a separate html file (lets call it pick-filters.html). On that new html file, have a new ng-app and therefore a separate app.js file for this particular page. In this new app.js file (lets call it pick-filters-app.js), you can use the app.config snippet that you have shown here. This should fix your problem of all pages not reloading because only pick-filters.html is referencing pick-filters-app.js which has this config snippet.
I have an angular controller that is dynamically populating ui-sref parameters
the url does not resolve and I think its because ui-router resolves urls before my controller has a chance to populate the params because it gets the params through a get to the backend.
If I manually specify the variable without querying the backend first it works
with the controller after the page loads you can see the html in the end is correct, just that ui-router never got a chance to resolve it
Is it the loading order ? or something else
I am absolutely novice to angular.js and i have some confusion, is it compulsory to define ngRoute on the angular module, as far as i think that it is require to include if we want to change the view on the basis of URl change.
Or is it also possible to define the route and return the view manually by calling some controller and on button click and it will return a view that i can use in the my index page.
You can create a app without using ngRoute. In that case you do not use the nv-view directive in html and the app does not respond to url change.
Also in that case if you want to change any part of the site, you use ng-include which takes parameter as the view name on server and it can be dynamically changed based on some logic.
Said that, you should use the view segregation and loading based on route as it makes your application a truly single page app, where views are update without any page refresh and each of the individual views can be bookmarked.
When a use visits a private page unauthorized, say profile, my backend 302 redirects to a controller action that serves up the login partial in place of the profile partial. Since it 302 redirects to an action that returns a partial, the url address bar doesn't change from the page the user was trying to access ("/profile").
I was going to "fix" that but actually I think it makes a good user experience instead of dealing with return urls as query params.
The idea is once they log in I just want to reload the current route aka do a GET request for the profile partial via "/profile" and switch it back in instead of the login partial.
However, I can't get this "reload current route" to work. I tried all of the following:
$location.$$compose();
$location.absUrl($location.path());
$location.url($location.path());
$location.path($location.path())
$route.reload();
But none work. $route.reload() seems to be the definite way but it also doesn't work. It goes through the route cycle, reinstantiates the controller, but does not do GET request to reload the template
The only thing that works is a hard refresh via location.reload() but that is not ideal.
How can I force angular to reload the template for the current route?
Ok I found the solution provided by lgalfaso on Github (exact paste):
Templates are
cached, if a user does not have the permissions to be in a page, then
this check should be done before it reaches the controller or after,
within the controller, but not on the template retrieval
If this is the way you want to follow, then you need to remove the
template from the $templateCache before you call reload
So that worked for me because login template actually gets cached as the template the user was trying to access. So removing it and letting angular re-fetch the correct one for the current route worked like a charm.
var currentPageTemplate = $route.current.templateUrl;
$templateCache.remove(currentPageTemplate);
$route.reload();
I have noticed that $route.reload() method re-instantiates everything that is setup on your $routeProvider.when("/someUrl",{controller:'SomeController',templateUrl:'SomeView.html'}) template,controller and/or any resolved promises you may have passed within the .when() method.
Therefore; when you build your app, if you want $route.reload() to reload all the page and re-instantiate controllers you must put everything under your <div ng-view></div> container and include any menus or footers inside the templateUrl file.