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);
Related
In an AngularJS Single Page Application, if you are in the main page and now you route to the second page, and use the "service" (as a global), and use myService.cityName to pull data using AJAX (by using $resource), that's fine.
But what if on your page header, you also have an input text box, and you can type in a city name, and when the user press Enter, you are routing to the same page (the second page). So I think browser didn't do anything because it is the exact same URL. How would you solve this issue or what is the AngularJS's way of handling this?
(Update: it is not to refresh or reload a page... it is about, say, you get weather data for a city, and you are on the forecast subpage, with a path of #/forecast. Now at the top search box on the page, you enter a different city and click "Submit" to go to the same path #/forecast then nothing will happen)
Update2: essentially, in my controller code:
$scope.submit = function() {
$location.path("/dataPage");
}
and my form is <form ng-submit="submit()">.
so if I am already on the dataPage, then now browser wants to go to dataPage to show new data, but since the path and hash is exactly the same, the browser just will not do anything. (I suppose due to no hashchange event happened, so nobody will notify AngularJS to do anything)
Your question is unclear, if you want a page refresh like F5, one solution is at "Solution for refresh page". But if you just want to reload things, you could follow "Solution for reload page".
Solution for refresh page:
To update a page, all that you need to update the model data of controller and the page will be updated accordingly. Ideally, you should never refresh an entire page in AngualrJS . If you need to do so, you are not using AngularJS correctly .
The $location service does not provide access to refreshing the entire page. If you need to refresh the entire page, you need to use the $window.location object.
$window.location.href = "YOURPAGEPATH";
Solution for reload page:
just want to reload things under ng-view, re-initialized the current route controller, you could do like below.
$route.reload("YOURPATH");
$route.reload() will reinitialise the controllers but not the
services.
If you want to reset the whole state of your application you can use:
$window.location.reload();
This is a standard DOM method which you can access injecting the $window service
Also see: $route documentation
According to $route documentation:
Causes $route service to reload the current route even if $location
hasn't changed. As a result of that, ngView creates new scope,
reinstantiates the controller.
Well you can just save data from request on your global service. And in controller you can bind that data, so if you press submit from header that function should just refresh your data in service.
I am having some trouble understanding the difference between all those $state, $stateProvider and $routeProvider.
The problem is that I am trying to implement an infinite-scroll in a simple app with posts. Since I managed to do that, the nested urls for more info about the post are not working. Here is a link from plnkr.co (http://embed.plnkr.co/66hgiIxNGTXOuVZgqKvZ/preview)
When on the feed tab everything seems fine, but when a link is clicked, empty page is displayed.
Let me try to make it simple.
$stateProvider
To maintain application's state and provide a basic block to configure URL to represent view accordingly.
Each part of the state represents.
url : The URL route that can be accessed via href properties
templateUrl: The path to the view template HTML file
controller : The controller to be used in this view
$urlRouterProvider
Simply use for routing the user to specified url. where .otherwise method do route to the default url when the path doesn't match any of the urls you configured.
in your example you should handle the parameter in your controller to render the detail page.
I recommend you to follow this example to understand how navigation and routing can simply implement in your application.
I'm structuring a Multi Page App in angular. I have a main app with its ngRoute configured so that the resulting url is something like:
http://localhost:8080/project/main#firstTemplate
http://localhost:8080/project/main#secondTemplate
http://localhost:8080/project/main#thirdTemplate
...
Now I must move to another app in the same project so that the Url is something like:
http://localhost:8080/project/secondary#fourthTemplate
I'm able to achieve this by manipulating the string resulting by $location.absUrl() and pass it to $window.location.href but it's horrible.
Is there a better way to do the same thing?
You should do this by the means of your router. There is a default router in angular, though I would suggest you going with https://github.com/angular-ui/ui-router - as I think it is much better than Angular v1.x defaults.
With that router you can define few states (1 state per each URL), define URL for each state, define views to be displayed in that state, actions on entry/leave etc. Then, you can get access to $state object and its go() method to switch between states - as well as easily have it done automatically on elements by specifying .
Is it possible with ngRoute to route to the current path? Essentially, I have a scenario where my app will route to a controller/view, then after a little bit of time an event handler can be executed in another part of the application which changes a global object, and the same controller/view should be executed again. I tried just routing to the same path (using location.path), but it appears that ngRoute ignores the request it the apps is currently on that path.
Going by the documentation you can use the $route.reload() method:
Causes $route service to reload the current route even if $location hasn't changed.
As a result of that, ngView creates new scope and reinstantiates the controller.
Recently I found out about the undocumented $locationChangeStart event in AngularJS when trying to determine where in the framework I should be redirecting users to the login page if their session is invalid.
I'm listening for the event using the following:
$scope.$on("$locationChangeStart", function (event, nextLocation, currentLocation) {
// Logic goes here
});
where nextLocation and previousLocation are absolute urls to locations within the app.
My question is this: Does AngularJS expose the ability to be able to match a url against a route, much like its internal routing engine does to see if an absolute URL matches a defined route?
If not, what would be the best way to detect a route based on an absolute URL?
I located the relevant source code lines in the AngularJS github project. Here is the function that it uses to match the URL to a route:
Since this functionality is not exposed by Angular I decided to come up with a rudimentary way of matching the URL to a route since the routes I was matching were relatively simple compared to implementing the same route matching that Angular does.
It ain't pretty, but it works..