ui-route how to render multi ui-view when route to template - angularjs

my requirement is:
index.html
-- /login
-- /main/tab1
-- /main/tab2
-- /userinfo
And the ui will be like:
header: logo, userinfo
left-nav: switch tab1/tab2/tabN
right content: ui-view to change, and multi sub ui-view,
And UI detail:
login will be a independent page, no header, left-nav, right content
main/tab will only change the right content
/userinfo will replace the left-nav and right content to some userinfo page, remain the header, of course using ui-view
I've seen the ui-route demo, but follow the demo, I don't know how to build the route config to what I want, so could any one help me ? The ui-route config is a little complex.....
If my url define is not perfect, please help me improve the url structure, thanks

If you have seen the demo and understood it, this should make sense:
.state('index', {
url: '/',
templateUrl: //your index.html template path,
controller: // your controller if any for index page
})
.state('index.login', {
url: '/login',
templateUrl: // your login template,
controller: // controller for login page
})
.state('index.mainTab1', {
url: '/main/tab1',
templateUrl: // your tab1 template,
})
add the other states in the same manner and you should be ready to go.

Related

$urlRouterProvider.otherwise not going to default route

I am stuck with this for a while. I am very much new to ui-router's nesting of views. I am trying to route to default when "/" accessed. Here's my js file:
angular
.module("app")
.config(function($stateProvider,$locationProvider,$urlRouterProvider){
$urlRouterProvider.otherwise("dashboard");
$stateProvider
.state("home",{
url: "/",
templateUrl: "views/home/home.html"
})
.state("login",{
url: "/login",
templateUrl: "views/login/login.html"
})
.state("home.dashboard",{
url: "/dashboard",
templateUrl: "views/home/dashboard.html"
});
$locationProvider.html5Mode(true);
});
I don't know why that's not working. Every time I try to load localhost, it's not going to localhost/dashboard. Rather, it stops loading till home.html. Please help me in learning something new and showing my mistake.
Please see this working plunker. I turned off the HTML5 mode because it prevents plunker to work correctly.
The main problem with your code was that you were redirecting to /dashboard, in this statement:
$urlRouterProvider.otherwise("/dashboard");
Please note that home.dashboard is a child state of home. So, by default, the URL should be preceded by that of the home state. So the correct statement would be:
$urlRouterProvider.otherwise("/home/dashboard");
If you don't want the preceding /home, you need the change your route configuration for home.dashboard state to this:
.state("home.dashboard", {
url: "^/dashboard",
templateUrl: "dashboard.html"
});
The preceding ^ makes the URL absolute and makes it free of any preceding parent state's URL. So now, the statement $urlRouterProvider.otherwise("/dashboard"); will work as is.
After this change, the code could load the template home.html in the view. Further, you didn't have any ui-view directives in home.html in which the template of home.dashboard could load. So I added a <div ui-view></div> element in home.html to make it work correctly.

Components aren't being injected into my ui-view

I'm just trying to setup a boilerplate for angular 1.5.9 with UI Router 1.0.0. I can display my parent state component within the ui-view, however when I nest states within my parent, my components aren't being injected into my ui-view.
This is my index.html
<body ng-app="app">
<ui-view></ui-view>
</body>
This is the main component
<div class="main-container">
<banner></banner>
<div ui-view='ui-view></div>
</div>
It is at this point where in I'm unable to inject anything into the ui-view.
This is my javascript file
$stateProvider
.state('app', {
url: '/',
component: 'main'
})
.state('app.login', {
url: '/login',
views: {
'ui-view': {
templateUrl: './app/login/login.html'
}
}
});
I'm not sure what I'm doing wrong, any help/direction to the right path would be appreciated.
EDIT
Additional Info that might be helpful
When I reference login as a parent state everything works as expected.
The login component is part of a separate module that I've included in my main module.
For nesting one child state in each parent component, there is no need to use named views as you did by adding a value of "ui-view" for the ui-view directive used in your main component template. Those named views are only required when you want to address more than one ui-view. Then you need to reference them by name.
In your sample, you will not see any content because you also don't target the named view correctly. There are some rules on how to address those named views if the named views are defined in a template which is not the root file. In that case you need to be more specific by referencing the ui-view with a "ui-view-name#state" syntax which would mean "ui-view#app" in your case.
But as already mentioned: In your simple case, just leave out the name for the ui-view and replace the views section in your state config with a plain template (or a component reference).
.state('app.login', {
url: '/login',
templateUrl: './app/login/login.html'
});
For details on nesting views, please have a look at the great sample apps in the ui-router docs.
So this one is really strange, I've no explanation as to why it worked the way it did. All I did was change the javascript file to the one below
$stateProvider
.state('login', {
url: '/login',
component: 'main'
})
.state('login.default', {
url: '/default',
component: 'login'
});
Instead of my parent having '/', changed it to '/login'. I'd be keen to know if someone knows the reason behind this behaviour.
$stateProvider
.state('app', {
url: '/',
templateUrl: path/to/main_component.html
})
.state('app.login', {
url: '/login',
views: {
'ui-view': {
templateUrl: './app/login/login.html'
}
}
});
When you are in app.login view(state) ui-view will be checked in its parent states template. If you don't have a template, it doesn't know where to render.
'ui-view':{} is targetted to its parent view.
'ui-view#':{} is targetted to the root component that is index.html

Angular UI router dynamically inject URL to html

I am trying to build a simple app, which goes the following way:
I have 2 menu items in the navbar: home and contact.
The home should be a unique URL only once from the server, at initialisation, read from a QR code (i got this covered, that is no problem to me) and the contact should always be the same.
I got the contact done in the following way:
$stateProvider.state('contact', {
url: '/contact',
templateUrl: 'src/views/contact.html',
controller: 'contactController'
})
The problem is with the home, which should keep the unique URL received by the server. How should i write the state for that one?
.state('home', {
url: '/:uid',
templateUrl: 'src/views/home.html',
})
Also, the home should keep it's unique url generated by the server after refresh and while navigating from contact to home.
In the HTML i would have something like
<a ui-sref="home({uid: --some dynamic uid?--})">Home</a>
this is the part which also requires help.
Set the home state to
.state('home', {
url: /{uid},
templateUrl: 'src/views/home.html',
})
and you could grab the parameters by injecting $stateParams into the controller. $stateParams.uid would return the parameters and store that in local storage or cookies.
Check this link out
https://github.com/angular-ui/ui-router/wiki/URL-Routing#stateparams-service
UPDATE:
for example, this is the sample controller that is attached to the home page
app.controller('homeCtrl', function($stateParams) {
var id = $stateParams.uid; //this is how you retrieve the uid
});
by going to your home page e.g. http://www.example.com/abcd12345, the above $stateParams.uid would return abcd12345
Now to set the url. simply use ui-sref instead of href on the <a> tag. ui-router will automatically generate href for you.
e.g.
<a ui-sref="home({uid:'abcd12345'})">Home</a>
You have to create a custom provider and inject it into the config.
eg:- .config($stateProvider, $urlRouterProvider,yourprovider) .
I am not sure about this. But please check this way too..

How to switch to a ui-router state conditionally?

I am writing a CRUD app with AngularJS + UI Router.
I want to be able to parse the current location in the browser URL and determine if a ui-router state should be applicable for the current url.
In these sample routes, is there some way to do the if and unless clauses?
(url in browser address bar is http://example.com/notes/1/edit_me)
$stateProvider.state("root", {
url: "",
unless: $location.matches(/\edit_me/)
})
$stateProvider.state("edit", {
url: "/edit",
if: $location.matches(/\edit_me/)
//
})
UPDATE 1
The reason I want to do the above:
Say I am at http://example.com/notes. The routes is
$stateProvider.state("root", {
url: "",
})
However, with the same above ui.route state, when I am at url http://example.com/notes/edit, the root is now "/notes/edit" instead of "/notes"
UPDATE 2
#adam, more explanation of what I am trying to accomplish:
I will try to explain: in your code, for your home state, the (ui.router's) url is / (aka hash syntax #!/)
However, the URL in browser address bar looks like http://example.com/notes/ in one case and http://example.com/notes/edit in another case. (note that the URLs do not contain any #! portion since we have just navigated to the page)
Now the home's / is going to match in both cases of above URL.
But since the second URL ends in notes/edit, I want that the home for this URL should be #!/edit, and not #!/.
Basically I am trying to mix server-side rendered pages (/notes and /notes/edit are rendered by server, not AngularJS)
and client side routing so that no matter which URL we are at, the client can figure out which (ui.router) route applies to the current URL.
Make sense?
Sorry i don't really understand your needs but here's an example of use of ui-router:
$stateProvider
.state('home', {
url: '/',
templateUrl: 'app/main/index.html',
controller: 'MainCtrl'
})
$stateProvider
.state('edit', {
url: '/edit',
templateUrl: 'app/edit/edit.html',
controller: 'EditCtrl'
})
$stateProvider
.state('edit.note', {
url: '/note',
templateUrl: 'app/edit/note.html',
controller: 'NoteCtrl'
});
$urlRouterProvider.otherwise('/');
i'm not sure if a copy paste will work, but try to adapt it with your case. Hope it will help.
Edit:
I'm afraid that i can't help you more than that. The design of your app with rendered page without angular sounds really special.
Have you tried the example i provide you? If yes, hav you simply format the url by addind
" #!/ " where you need it.
For example:
$stateProvider
.state('edit', {
url: '#!/edit', //or something like, url:'/#!/edit'
templateUrl: 'app/edit/edit.html',
controller: 'EditCtrl'
});
Check this link also may be it will help you:https://github.com/angular-ui/ui-router/issues/372
ui-sref may help you
But the place to see usefull example for ui-router it's his own doc.
https://github.com/angular-ui/ui-router
and here:
http://angular-ui.github.io/ui-router/site/#/api/ui.router

AngularJS multiple routes using JSON data ids

We are new to AngularJS and finding one-or-two problems with setting up multiple routes when using ID's from Json Data.
We are trying to replicate AngularJS Tutorial, so we can click each 'View' button to display a more detailed page of the selected 'Warranty Item' same as the tutorial.
We have uploaded our AngularJS problem to Plunker, If anyone can see something we're missing or know a better route to go down please let us know.
App.js State with ResultSet.JobID
.state('home.singleWarranty', {
url: '/singlewarranty/{resultset.JobID}',
templateUrl: 'singlewarranty.html',
controller: 'warrantyListController'
})
There is a working/updated plunker
Because there are these states
.state('home', {
url: '/home',
templateUrl: 'home.html',
controller: 'homeController'
})
.state('home.singleWarranty', {
url: '/singleWarranty/:jobID',
templateUrl: 'singlewarranty.html',
controller: 'warrantyListController'
})
We need to build the url like this
View
Instead of this original
// View
The point is that state 'home.singleWarranty' inherits/extends the url from its parent. So we have to include the parents '/home' as well.
Other solution:
In case we would like to start the url in a child state from the begining, we can do it like this
.state('home.singleWarranty', {
url: '^/singleWarranty/:jobID',
See the ^ at the url begining. Then even this would work:
View
Check the updated plunker here

Resources