$state and $stateProvider unusual behaviour while using an infinitescroll and a for loop - angularjs

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.

Related

How to use angular ui router on "normal sites" without HTML5 mode?

In our team, we want to use angular-ui-router to assign a "state" by reading the url without hashbangs or html5mode, so that 1. We programmatically assign controllers based on "normal" urls and 2. We support ie9
We can't support hashbangs (which would give use ie9 support) because we are running this on a "non-spa website" and the urls are rendered server side. We literally just want to assign a state by reading a normal url on page load.
This seems trickier than I previously thought. Consider the following routes:
//Parent view
.state('abc', {
abstract: true,
controller: 'MainController'
})
//Search
.state('abc.Search', {
url: '/booking/search',
controller: 'SearchController'
})
Here is the goal: We want the whole path http://website.com/booking/search to pick up the state NOT http://website.com/#/booking/search, and we can't remove the # by adding html5mode.
If we try to add html5mode the page keeps refreshing in ie9 (we dont support ie8).
Now I know that we can remove state-routing and go back to adding ng-controller to the template, however we are in a unique position where we need to be able to programmatically assign controllers based on the url. This is the advantage on using angular-ui-state router.
Thanks in advance.

ui-router for manual parsing URL without using views

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);

Angularjs: use config only for one controller

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.

Autonomous routing on AngularJS

I am working on a project with more 300+ pages based on AngularJS.
Everything is all right, but I'd like to find a way to get rid of those 300+ lines for routing.
Here my thoughts :
User goes on url /settings/company
AngularJS has to load templateUrl at '/template/'+settings/company+'.html'
Then AnguarJS loads controller SettingsCompany+'Ctrl'
Do you think if it is possible ?
If you are using ui-router which I would recommend you can create your routes Dynamicly all you need to do is
var state = {
url: someUrl
template: someHtml
controller: someController
};
$stateProviderRef.state(TheStatename, state);
You obviously need to do that before loading the view. I personally have a static login in my app and after i know which user logged in i load different modules and with this i basicly create the states dynamicly and load the Controller files with lazyload.
Hope this was helpful

render templates for a specific route directly from the server

when using routes in an angular.js application is it possible to render the template for a specific route directly from the server and then attach your controller to it?
For example, i have an application with a login screen and a screen which shows some content when the user is logged in.
When the user isn't logged in and he opens the application it would be cool if i could render the template for the login route directly from the server and then attach the right controller to it. So that the user gets feedback directly and doesn't have to wait until angular.js is bootstrapped before the page shows anything.
When the user is logged in and he opens the application i want to render the template for the content page directly from the server and then attach the controller to it as you would do when you don't use the routing from angular.js (with ng-controller for example). Some stuff on this page will be cloacked because it needs the controller attached to it before it shows anything useful.
I'm quiet new to angular, i just experimented a bit with angular.js and the routing api. But in my test application when i open it, it first shows nothing and then when angular is bootstrapped it renders the view for the "/" route. I want to show the view direcly because some of the information doesn't need the controller attached to it. Other things i can hide using ng-cloack or ng-bind. But this way it will be much cleaner.
Doesn anyone has an idea how to achieve this? If my explanation still is a bit unclear, let me know. I found it hard to explain this ...
kind regards,
Daan
Honestly, I never tried this solution, but I guess the controller template has not necessarily to be a static file.
You need to provide a path to your template, but it could be created dynamically.
For example:
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'myApp.controllers']).
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/login', {templateUrl: 'partials/login.php', controller: 'LoginCtrl'});
$routeProvider.when('/logout', {templateUrl: 'partials/logout.php', controller: 'LogoutCtrl'});
$routeProvider.otherwise({redirectTo: '/login'});
}]);
login.php and logout.php must return a valide AngularJS template.
I never tried this, but it should work.
I don't know if this is the Angular way of doing things.

Resources