The site I'm building already has URL's built up using MVC. So for example /Account goes to a page, /Customers goes to a page, and /Quotes goes to a page. On the /Quotes page I have a multi-step wizard which I want to use Ui-Routing on. See my app.js below, this all works.
So my URL becomes /Quotes#newmodel, /Quotes#customer, etc. A different #{value} for each step on the wizard. The problem is that the .otherwise affects all other areas of the site. So if I'm going to /Account, I get the url /Account#wizard. I do not want this to occur anywhere other than on the /Quotes page. Is there anything I can do with the URL matching so I can remove the .otherwise?
'use strict';
var myApp = angular.module('myApp', ['ui.router']);
myApp.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/wizard");
$stateProvider
.state('wizard', {
url: '/wizard',
templateUrl: 'Scripts/templates/wizardLayout.html',
controller: 'wizardNavigationCtrl'
})
.state('wizard.newmodel', {
url: '/newmodel',
templateUrl: 'Scripts/templates/wizardModel.html',
controller: 'wizardModelCtrl'
})
.state('wizard.other', {
url: '/other',
templateUrl: 'Scripts/templates/wizardOther.html',
controller: 'wizardOtherCtrl'
})
.state('wizard.customer', {
url: '/customer',
templateUrl: 'Scripts/templates/wizardCustomer.html',
controller: 'wizardCustomerCtrl'
})
.state('wizard.shipping', {
url: '/shipping',
templateUrl: 'Scripts/templates/wizardShipping.html',
controller: 'wizardShippingCtrl'
})
.state('wizard.review', {
url: '/review',
templateUrl: 'Scripts/templates/wizardReview.html',
controller: 'wizardReviewCtrl'
});
}]);
I'm also interested in how I can cause the route to load the layout and then by default go to the wizard.newmodel route (though this may be a separate question). Basically the same behavior as if I click on an:
<a sref-ui=".newmodel">
I removed the $urlRouterProvider.otherwise("/wizard") in the app.js.
Instead I added a controller to the main /Quote page that redirects the $location.url to '/wizard'. Below is the code.
myApp.controller('wizardCtrl', ['$location', function ($location) {
$location.url('wizard')
}])
Related
I have an app.config with UI-Router. It has a login page with it's controller, recoverLogin and I want to put a template with footer, header and more stuff with new states that could be loaded into the template (in an especificplace).
My module is:
var app = angular.module("app", [
"ui.router",
"pascalprecht.translate"
]);
My routes are;
app.config(function($stateProvider, $urlRouterProvider)
{
$stateProvider
.state("login", {
url: "/login",
templateUrl: "views/accessControl/login.html",
controller: "loginCtrl"
});
$stateProvider
.state("recoverLogin", {
url: "/recoverLogin",
templateUrl: "views/accessControl/recoverLogin.html",
controller: "recoverLoginCtrl"
});
$stateProvider
.state("template", {
url: "/template",
templateUrl: "views/templates/template.html",
controller: "templateCtrl"
})
.state("template.dashboard", {
url: "/dashboard",
templateUrl: "views/dashboard/dashboard.html",
controller: "dashboardCtrl"
})
$urlRouterProvider.otherwise("login");
})
I have in my index <ui-view></ui-view> for the place of the loadings and another <ui-view></ui-view> in template.html int he place where I want to load more stuff like dashboard.html, but this doesn't works. it loads dashboard.html without the template created in template.html. I have founded lot of documentation that doesn´t works for me. Any Idea?
Here there are a plunker example of the idea: https://plnkr.co/edit/ZsGZjDKOBTIXFpPtXasN?p=preview
There is updated plunker and working plunker.
The template of the mainTemplate state is now lookin like this:
place for main:
<div ui-view="main"></div>
place for other:
<div ui-view="other"></div>
so it has two (could be more) places for more stuff. And this is the state redefined:
.state("mainTemplate.dashboard", {
name: "main",
url: "/dashboard",
views: {
'main' : {
templateUrl: "dashboard.html",
controller: "dashboardCtrl"
},
'other' : {
template: "<h2>other view</h2>",
}
}
});
What we can see is views : {} object being used to defined multiple content for more targets. Read about that more details here:
Angular UI Router - Nested States with multiple layouts
Nested states or views for layout with leftbar in ui-router?
play or observe the changes here
I have set up within angular 1.5 the Ui-router as follows:
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('blank', { url:'/blank', templateUrl: 'home/blank.html' })
`enter code here` .state('verify', { url:'/verify/:type', templateUrl : 'update/verify.html', controller: function($scope, $stateParams, general) { general.verifyemail($stateParams.type);} })
.state('home', { url:'/', templateUrl: 'home/home.html' })
.state('about', { url:'/about', templateUrl: 'about/about.html' })
.state('faq', { url:'/faq', templateUrl: 'faq/faq.html' })
.state('exercise', { url:'/exercise', templateUrl: 'practice/exercise.html' })
.state('levels', { url:'/levels', templateUrl: 'practice/level.html' })
}]);
the router works when the app is already started but if you extend the url to include the path i.e. myapp/about and paste the url into a new browser window, the browser will open the app but go to the home page. If you paste the same url into the page already loaded, it goes to the right state.
I've obviously set it up wrong but I can't figure out why.
Have you tried to use # before route name?
Like: myapp/#/about
I have the following code for states:
.config(function ($stateProvider, $urlRouterProvider, CONSTANTS) {
$urlRouterProvider.otherwise('/cyo');
$stateProvider.state('pri', {
url: '/pri',
controller: 'priController',
templateUrl: CONSTANTS.PRI_TEMPLATES.PRI_TEMPLATE_URL,
redirectTo: 'pri.size'
}).state('rec', {
url: '/rec',
controller: 'recController',
controllerAs: 'recCtrl',
templateUrl: CONSTANTS.REC_TEMPLATES.REC_TEMPLATE_URL
})
});
The URL is being generated is http://adc.com/REC/1440/#
1440 being a ID that changes depending upon a prod Cat. the template is not loaded with this url. but as soon I add '/rec/' after the current url the template is loaded - http://adc.com/REC/1440/#/rec/ the page loads correctly
I am not able to understand how to get this fixed.
Ayush
You should define the state paramaters when you define the state.
Try this:
.state('rec', {
url: '/rec/:id',
params: {id: 'defaultValue'}, // optional
controller: 'recController',
controllerAs: 'recCtrl',
templateUrl: CONSTANTS.REC_TEMPLATES.REC_TEMPLATE_URL
})
And the html code:
<a ui-sref='rec({id: 123})'>Go to rec</a>
Here is the plunker link for the code http://plnkr.co/edit/JwM8t3oNepP3tE1nUXlM?p=info
controller.js
if(($scope.login==='Admin')&&($scope.password==='admin'))
{
$state.go('login.home');
}
script.js
var DailyUsageApp = angular.module('DailyUsageApp', ['ui.router']);
DailyUsageApp.config(function($stateProvider, $locationProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider.state('login', {
url: '/login',
templateUrl: "login.html",
controller: 'authController'
})
.state('login.home', {
url: '/home',
templateUrl: "home.html",
controller: 'homeController'
});
});
The reason your code isn't working is because you are creating hierarchical states, that are not meant to be hierarchical. By naming your state login.home, you are saying that home is a child of login. This means that when you try and go('login.home') ui router is attempting to render the login state as well as the home state as a child. This means that for your current layout to work, the login template must contain its own ui-view tag. The best way to fix this is to simply rename your state to just home, and then use $state.go('home');
There is an updated plunker
The most simple solution is to NOT make state login.home nested under login.
//.state('login.home', {
.state('home', {
url: '/home',
templateUrl: "home.html",
controller: 'homeController'
});
There are also other solutions, like create a target for login.home inside of the login like this:
<div ui-view=""></div
But usually, we do not do that. Just login and then navigate to some other state hierarchy...
Needs some guidance with respect to migrating my ngRoute configuration to a ui.router configuration. Currently I have one main template (index.html) and it has an ng-view where all views are injected. My current ngRoute config is as follows:
app.config(function ($routeProvider) {
$routeProvider
.when('/login', {
templateUrl: 'app/views/login.html',
controller: 'LoginCtrl'
})
.when('/contact', {
templateUrl: 'app/views/contact.html',
controller: 'ContactCtrl'
})
.when('/notification', {
templateUrl: 'app/views/notification.html',
controller: 'NotificationCtrl'
})
.otherwise({
redirectTo: '/login'
});
I now want to define a second place in index.html where I can inject some view content - not a nested view, but rather another ng-view (or ui-view in ui-router terminology). The original ng-view section is the default one (currently just for /login and /contact), and the new one is just for specific routes (currently just '/notification' but maybe others in the future). Lets call the new ui-view 'notification-view'.
I've gone through much of the ui-router documentation and still am unsure of how to migrate the above to the new ui.router config. Can someone get me started or point me toward some decent examples?
Update:
Ok, here is where I am. I've adding some states and a new ui-view to my index.html page. See below:
<div class="container">
<div id="header"></div>
<div data-ui-view></div>
<div data-ui-view="notification-view"></div>
</div>
My routing is now:
app.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/login');
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'app/views/login.html',
controller: 'LoginCtrl'
})
.state('contact', {
url: '/contact',
templateUrl: 'app/views/contact.html',
controller: 'ContactCtrl'
})
.state('notification', {
url: '/notification',
views: {
"notification-view": {
templateUrl: 'app/views/notification.html',
controller: 'NotificationCtrl'
}
}
});
});
This seems to work ok for the most part. When the url /notification is triggered, the app is routed to the NotificationCtrl and renders ui-view content into the notification-view. However the only problem is that the ui content in the main (unnamed) ui-view is lost. I would like whatever is already rendered in the main ui-view to be untouched, and only target the notification-view. Is this possible? Does it have to instead be a nested-view?
When using ui.router, you should think in terms of states rather than routes. So instead of the $routeProvider you instead inject $stateProvider, plan out various states and work from there . So from your example above, we convert it to:
app.config(function ($stateProvider,$urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$stateProvider
.state('login', {
url:'/login',
templateUrl: 'app/views/login.html',
controller: 'LoginCtrl'
})
.state('contact', {
url:'/contact',
templateUrl: 'app/views/contact.html',
controller: 'ContactCtrl'
})
.state('notification', {
url:'/notification',
templateUrl: 'app/views/notification.html',
controller: 'NotificationCtrl'
});
}
There's alot of methods for adding a "sub-view" to uirouter, one method is by adding a child state.
$stateProvider
.state('login', {
url:'/login',
templateUrl: 'app/views/login.html',
controller: 'LoginCtrl'
})
.state('login.error', {
url:'/login',
templateUrl: 'app/views/login-error-subview.html',
controller: 'LoginErrorCtrl'
})
Also as $stateProvider doesnt provide a default state handler, you will also need to inject in $urlRouterProvider. This is a provider that also comes with ui-router that is tasked with the responsibility of watching $location for changes.
The thing with ui-router is that you won't see a huge difference compared to the built-in route provider and ease of use it brings until you start using sub-states and stacked-states.
In your example above, ui.router wouldnt know what templte to use tor the ui-view and thus leaves it empty. You can give it a template and thus becomes:
...
.state('notification', {
url: '/notification',
views: {
'':{
templateUrl: 'app/views/notification-main.html',
controller: ''
}
'notification-view': {
templateUrl: 'app/views/notification.html',
controller: 'NotificationCtrl'
}
}
...
But from what I'm getting you want the login and contact to have the notification in it. So ideally you'd create a notification child state for each, as right now there is now way to declare wildcard or multiple parents for a child-state. Hopefully when v1.0 comes out there'll be support for this use-case already.
Below is a link from the docs that will get you upto speed:
https://github.com/angular-ui/ui-router/wiki/URL-Routing
https://github.com/angular-ui/ui-router/wiki/Nested-States-%26-Nested-Views