In my app, I require to attach multiple url with same state - how do i achieve this?
here is my existing state:
.state('createCase', {
url: '/createCase',
templateUrl: null,
controller: null,
data: {
requireLogin: false
},
also I would like to attache another url as like this:
.state('createCase', {
url: '/createCase?sn=12345', //(12345 is dynamic )
templateUrl: null,
controller: null,
data: {
requireLogin: false
},
here is my current function:
function routeConfig($stateProvider, $locationProvider, $urlRouterProvider) {
$stateProvider
.state('login', {
url: '/',
templateUrl: function(){
console.log('from 1oauth');
return 'app/login/login.html';
},
controller: 'loginCtrl as ctrl',
data: {
requireLogin: false
}
})
.state('oauth', {
url: '/oauth',
templateUrl: function(){
console.log('from 2oauth');
return 'app/oauth/oauth.template.html';
},
controller: 'OAuthController as ctrl',
data: {
requireLogin: false
}
})
.state('createCase', {
url: '/createCase',
templateUrl: null,
controller: null,
data: {
requireLogin: false
}
}
})
// if (isWeb()){
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
// }
// $urlRouterProvider.otherwise('/');
$urlRouterProvider.otherwise('/');
}
You don't need to define two different states for same url. In your controller, you can use $state.params object that has query parameters as properties.
Your route
.state('createCase', {
url: '/createCase',
templateUrl: null,
controller: 'MyCtrl',
data: {
requireLogin: false
},
params: {
sn: null
}
Your controller
function MyCtrl($state) {
console.log($state.params);
}
Define in your route:
.state('createCase', {
url: '/createCase?sn', // bind your query param to URL
templateUrl: null,
controller: null,
data: {
requireLogin: false
},
In your controller,
inject $stateParams to dependencies and use it with $stateParams.sn whatever you need.
Example:
$state.go('createCase', {sn:1234}); // move to state with a param
$stateParams.sn // get a value of ==> 1234
Looks like you want to create a parent state and sub states. If you just want to have access to $routeParams you can can pass them to the controller or leave them out when using same state.
(function () {
'use strict';
angular.module('app', ['ui.router'])
.config(routeConfig);
routeConfig.$inject = ['$stateProvider'];
function routeConfig($stateProvider) {
$stateProvider
.state('createCase', {
url: '/createCase',
template: '<h3>Create Case</h3><div ui-view="detail"></div>'
})
.state('createCase.detail', {
parent: 'createCase',
url: '/:sn',
views: { 'detail#createCase': {
template: '{{sn}}',
controller: function($scope, $stateParams){
$scope.sn = $stateParams.sn;
}
}
}
})
}
}());
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<script data-require="angular.js#1.5.x" src="https://code.angularjs.org/1.5.8/angular.js" data-semver="1.5.8"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.1/angular-ui-router.js"></script>
</head>
<body ng-app="app">
<ul>
<li><a ui-sref="createCase">createCase</a></li>
<li><a ui-sref="createCase.detail({sn:'123456'})">createCaseDetail 123456</a></li>
<li><a ui-sref="createCase.detail({sn:''})">createCaseDetail None</a></li>
</ul>
<div ui-view=""></div>
</body>
</html>
Related
I'm really lost. I use ui-route in my angular app and i'm trying to extend my base controller. My base controller (appCtrl) works but child controller (navigationCtrl) doesn't on URL app/welcome. Do you know why???
index.html
<body>
<div id="wrap">
<!-- View for login and login-choose -->
<div ui-view="login"></div>
<!-- View for app -->
<div ui-view="app"></div>
</div>
<!-- SCRIPTS -->
<script type="text/javascript" src="./js/jquery-1.11.0.min.js"></script>
<script type="text/javascript" src="./js/jasny-bootstrap.min.js"></script>
<script type="text/javascript" src="./js/angular.min.js"></script>
<script type="text/javascript" src="./js/angular-ui-router.min.js"></script>
<script type="text/javascript" src="./js/angular-touch.min.js"></script>
<script type="text/javascript" src="./js/app.js"></script>
<script type="text/javascript" src="./js/app.navigation.js"></script>
</body>
app.js
var app = angular.module('tvm', ['ui.router', 'ngTouch']);
app.config(function($stateProvider, $urlRouterProvider, $locationProvider) {
// For any unmatched url, redirect to /state1
$urlRouterProvider.otherwise("/");
// Set up the states
$stateProvider
.state('login', {
url: "/",
views: {
"login": { templateUrl: "./pages/login.html" }
}
})
.state('login-choose', {
url: "/login-choose",
views: {
"login": { templateUrl: "./pages/login-choose.html" }
}
})
.state('app', {
url: "/app",
views: {
"app": {
templateUrl: "app.html",
controller: 'appCtrl'
}
}
})
.state('app.welcome', {
url: "/welcome",
templateUrl: './pages/welcome.html'
})
.state('app.profile', {
url: "/profile",
templateUrl: './pages/profile.html'
});
// remove # from URL
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
});
app.controller('appCtrl', function($scope) {
$scope.parentMethod = function () {
alert('aaa');
};
});
app.navigation.js
app.controller('navigationCtrl', ['$scope', '$controller', function($scope, $controller) {
// extend app controller
angular.extend(this, $controller('appCtrl', {$scope: $scope}));
var nav = $('nav');
var content = $('#content, #bar');
var navWidth = nav.width() + 'px';
var navIcon = $('#bar .nav_icon .circle');
$scope.circleHover = function(e) {
navIcon.addClass('hover');
};
$scope.circleLeave = function(e) {
navIcon.removeClass('hover');
};
// open / close nav
$scope.toggleNav = function(e) {
if(nav.hasClass('visible'))
closeNav();
else
openNav();
};
// when swipe left to right open nav
$scope.openSwipeNav = function(e) {
openNav();
};
// close nav
$scope.closeNav = function(e) {
var elem = angular.element(e.target);
if( (nav.hasClass('visible')) && (!$(elem).is('#bar')) )
closeNav();
};
// when swipe right to left close nav
$scope.closeSwipeNav = function(e) {
closeNav();
};
var openNav = function() {
nav.animate({
left: 0
}, 400, function() {
$(this).addClass('visible');
});
content.animate({
left: navWidth
}, 400, function() {
$(this).removeClass('full');
});
navIcon.addClass('active');
};
var closeNav = function() {
nav.animate({
left: '-' + navWidth
}, 400, function() {
$(this).removeClass('visible');
});
content.animate({
left: 0
}, 400, function() {
$(this).addClass('full');
navIcon.removeClass('active');
navIcon.removeClass('hover');
});
};
}]);
You are providing the states in wrong way should use the below code. It may help you get out of your problem
// Set up the states
$stateProvider
.state('login', {
url: "/",
views: {
"login": { templateUrl: "./pages/login.html" }
}
})
.state('login-choose', {
url: "/login-choose",
views: {
"login": { templateUrl: "./pages/login-choose.html" }
}
})
.state('app', {
url: "/app",
templateUrl: "app.html" //no need to define the controller here. If this route is not usable else define the controller separately for both app and app.welcome
})
.state('app.welcome', {
url: "/welcome",
templateUrl: './pages/welcome.html',
controller: 'appCtrl' // need to mention the controller in which you wantto perform the functionality of app/welcome
})
.state('app.profile', {
url: "/profile",
templateUrl: './pages/profile.html'
});
Ok I managed to solve it by add angular.extend to base controller
app.controller('appCtrl', ['$scope', '$controller', function($scope, $controller) {
angular.extend(this, $controller('navigationCtrl', {$scope: $scope}));
}]);
And I call controller in my first state:
.state('app', {
url: "/app",
views: {
"app": {
templateUrl: "app.html",
controller: 'appCtrl'
}
}
})
Then it also fires navigationCtrl
I have application in angularJs and it will have different modules with different JS files.for js file optimization I am going to implement requireJS.
There is (broken) plunker
My angularJs code is like this in app.js:
var app = angular.module("webapp", ['ngRoute']);
app.run(['$rootScope', '$state','$urlRouterProvider',
function ($rootScope, $state,$urlRouterProvider) {
$urlRouterProvider.otherwise('/index.html');
$stateProvider
.state('root.home',{
url: '/index.html',
views: {
'header': {
templateUrl: 'modules/header/html/header.html',
controller: 'headerController'
},
'content-area': {
templateUrl: 'modules/home/html/home.html',
controller: 'homeController'
},
'footer': {
templateUrl: 'modules/common/html/footer.html',
controller: 'footerController'
}
},
data: {
displayName: 'Home',
}
})
.state('root.about',{
url: '/index.html',
views: {
'header': {
templateUrl: 'modules/header/html/header.html',
controller: 'headerController'
},
'content-area': {
templateUrl: 'modules/home/html/about.html',
controller: 'aboutController'
},
'footer': {
templateUrl: 'modules/common/html/footer.html',
controller: 'footerController'
}
},
data: {
displayName: 'About',
}
})
}]);
I added the following code in my main.js file
require.config({
baseUrl: "",
// alias libraries paths. Must set 'angular'
paths: {
'angular': 'http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.min',
'angular-route': 'http://ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-route.min',
'angularAMD': 'http://cdn.jsdelivr.net/angular.amd/0.2.0/angularAMD.min'
},
// Add angular modules that does not support AMD out of the box, put it in a shim
shim: {
'angularAMD': ['angular'],
'angular-route': ['angular']
},
// kick start application
deps: ['app']
});
and also added requirejs in html
<head>
<link rel="stylesheet" href="style.css">
<script data-main="main.js" src="http://marcoslin.github.io/angularAMD/js/lib/requirejs/require.js"> </script>
<script src="js/app.js"></script>
</head>
how can I define requirejs module or implement with my angularjs UI-Rooter?
EXTEND:
In your Example You added the above code in app.js
define([], function() {
var app = angular.module('webapp');
return app;
})
I added above code to script.js.Also In my app.js file contain all the UI router things and I changed the main.js with following code
require.config({
//baseUrl: "js/scripts",
baseUrl: "",
// alias libraries paths
paths: {
// here we define path to NAMES
// to make controllers and their lazy-file-names independent
"testController" : "modules/test/js/controller/testController",
},
deps: ['js/script'] // changed section
});
but in my browser console I am gettnig this error "NetworkError: 404 Not Found .../default/app.js" .how can I solve this issue.I directly added this js file through the html.but I am getting this error.
As discussed in comments and related to this plunker: http://plnkr.co/edit/iV7fuG5mkoTQ2JoKk9e0?p=preview
I followed the Q & A:
angular-ui-router with requirejs, lazy loading of controller
And updated that plunker and make it working.
There are many changes. E.g. we should keep a reference to controller providers:
var app_cached_providers = {};
app.config(['$controllerProvider',
function(controllerProvider) {
app_cached_providers.$controllerProvider = controllerProvider;
}
]);
And inside of our mapped controllers (e.g. controller_home.js) register that:
define(['app'], function (app) {
// the Content Controller
// is added into the 'app' module
// lazily, and only once
app_cached_providers
.$controllerProvider
.register('HomeCtrl', function ($scope) {
$scope.message = "Message from HomeCtrl";
});
});
Also, this would be a helper method to make other stuff a bit simplier
var loadController = function(controllerName) {
return ["$q", function($q) {
var deferred = $q.defer();
require([controllerName], function() {deferred.resolve(); });
return deferred.promise;
}];
}
And here we will use it to extend state definitions. Firstly the root state:
$urlRouterProvider.otherwise('/root');
$stateProvider
.state('root',{
url: '/root',
templateUrl: 'view_root.html'
});
Now states loading controller async way:
var root_home = {
//url: '/index.html',
url: '/home',
views: {
'' : {templateUrl: 'view_home.html', controller: 'HomeCtrl' },
},
data: {
displayName: 'Home',
},
resolve : { }
};
root_home.resolve.loadTopMenuCtrl = loadController("HomeCtrl");
var root_about = {
//url: '/about.html',
url: '/about',
views: {
'' : {templateUrl: 'view_view1.html', controller: 'View1Ctrl' },
},
data: {
displayName: 'About',
},
resolve : { }
};
root_about.resolve.loadContentCtrl = loadController("View1Ctrl");
$stateProvider
.state('root.home', root_home)
.state('root.about', root_about)
Check it all in action here
Hi I'm trying to dynamically create templates based on the uri eg, contacts/jane would use the template contacts.jane.html
contacts.js
'use-strict';
angular.module('meanApp')
.config(function ($stateProvider) {
$stateProvider
.state('contacts', {
url: '/contacts',
controller: 'ContactsCtrl',
views: {
'': {
templateUrl: 'app/contacts/contacts.html'
},
'list#contacts': {
templateUrl: 'app/contacts/contacts.list.html'
},
'details#contacts': {
templateUrl: function ($stateParams) {
return 'app/contacts/' + $stateParams.id + '.html';
},
controller: function ($scope, $stateParams) {
}
}
}
})
.state('contacts.details', {
url: '/:id',
controller: 'ContactsCtrl'
});
});
contacts.html
<div ng-controller="ContactsCtrl">
<h1>My Contacts</h1>
<div ui-view="details"></div>
<div ui-view="list"></div>
There is a working example. What we need here, is to define the template inside of the child state:
$stateProvider
.state('contacts', {
url: '/contacts',
controller: 'ContactsCtrl',
views: {
'': {
templateUrl: 'app/contacts/contacts.html'
},
'list#contacts': {
templateUrl: 'app/contacts/contacts.list.html'
},
'details#contacts': {
// this could be, filled on a contacts state
// with some default content
template: "place for detail",
}
}
})
// this state has the 'id' defined
// so, here we can decide which template to use
// based on the $stateParams
.state('contacts.details', {
url: '/:id',
views: {
"details": {
controller: 'ContactsCtrl',
templateUrl: function($stateParams) {
url = 'app/contacts/' + $stateParams.id + '.html'
return url;
},
}
}
});
Also, the controller is defined in state so the template contacts should/could for example look like this (no ng-controller):
<div>
<h1>My Contacts</h1>
<div ui-view="list"></div>
<hr />
<div ui-view="details"></div>
</div>
Check that in action here
Why is my ProjectsController undefined? I get this error message from my browser console.
you can check that for yourself see this plunker:
http://plnkr.co/edit/0DJ6W7QEPx2UzpdzDrVu?p=preview
'use strict';
angular
.module('projectplanner', ['ui.router'])
.config(function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/projects');
$stateProvider
.state('projects', {
url: '/projects',
views: {
'menu': {
template: 'Start your projects!'
},
'content': {
templateUrl: "projects.html",
controller: 'ProjectsController'
}
}
})
.state('projects.selected', {
url: '/:projectId'
})
.state('projects.selected.dates', {
url: '/dates/:date',
views: {
'menu': {
templateUrl: 'menu.html'
},
'content': {
templateUrl: 'dateplanner.html',
controller: 'DateplannerController'
}
}
})
});
'use strict';
angular.module('projectplanner').controller('ProjectsController', function ($scope, $state) {
});
you have not included its js
<script src="app.js"></script>
<script src="ProjectsController.js"></script>
corrected PLUNKER LINK
I'm using modules /sub modules on the angular app, my controller doesn't load on a specific route but the view does, according to a comment on this question I should reference the child module inside the main module and that should do the trick.
this is my code for bootstrapping the app:
angular.module('mainApp', ['ui.bootstrap', 'ui.utils', 'ui.router', 'ngResource', 'ngAnimate', 'ngCookies', 'facebook', 'subModule1', 'subModule2', 'subModule3']);
angular.module('mainApp').config(function ($stateProvider, $urlRouterProvider, $locationProvider, FacebookProvider) {
$stateProvider.state("root",
{
url: '',
abstract: true,
views: {
'footer#': {
templateUrl: "/partial/footer/footer.html",
},
'header#': {
templateUrl: "/partial/header/header.html",
}
}
}).state('root.home', {
url: '/index',
views: {
'container#': {
templateUrl: '/partial/index/index.html',
controller: 'IndexCtrl'
}
},
}
).state('root.login', {
url: "/login",
views: {
'container#': {
templateUrl: '/partial/login/login.html',
controller: 'LoginCtrl'
}
},
});
FacebookProvider.init('xxxxxx');
$urlRouterProvider.otherwise('/index');
$locationProvider.hashPrefix('!');
});
I have the sub-module configuration in a separate folder named /subModule1/submodule1.js
angular.module('subModule1').config(function($stateProvider) {
$stateProvider.state("submodule1",
{
url: '',
abstract: true,
views: {
'footer#': {
templateUrl: "/partial/footer/footer.html",
},
'header#': {
templateUrl: "/partial/header/header.html",
}
}
}).state('submodule1.dashboard',
{
url: '/dashboard',
views: {
'container#': {
templateUrl: '/subModule1/partial/dashboard/dashboard.html',
controller: 'DashboardCtrl',
resolve: {
dashboardinfo: function($resource) {
var resourceGet = $resource('/submodule1/dashboard');
return resourceGet.get().$promise;
}
}
},
'sideBar#': {
templateUrl: '/submodule1/partial/sidebar/sidebar.html'
},
'navBar#': {
templateUrl: '/submodule1/partial/navbar/navbar.html'
}
}
});
});
the controller is defined as:
angular.module('subModule1').controller('DashboardCtrl', function ($scope, $interval, $resource, notification, dashboardinfo) { ... }
the index located on the root of the page which is the page layout have the
<html ng-app="mainApp">
and the controller have the ng-controller definiton as follows:
<div ng-controller="DashboardCtrl">
Everything is fine just the controller isn't running, it doesn't get executed by the view.
The ui-router and ng-controller="DashboardCtrl" are intended to work together. In the ui-router world we are assigning Controllers to views directly in the state definition.
So this (exactly as you have already have it, no change) is enough:
.state('submodule1.dashboard',
{
url: '/dashboard',
views: {
'container#': {
templateUrl: '/subModule1/partial/dashboard/dashboard.html',
controller: 'DashboardCtrl',
to say, that the view rendered inside of the ui-view="container" on the root (index.html) should be provided with DashboardCtrl.
There is an example using the above state definition (1:1 as possible).
This is the index.html content:
<div ui-view="header"></div>
<div ui-view="navBar"></div>
<div ui-view="container"></div>
<div ui-view="sideBar"></div>
<div ui-view="footer"></div>
And this links will correctly trigger the above states:
// root
<li><a ui-sref="root.home">root.home</a></li>
<li><a ui-sref="root.login">root.login</a></li>
// dashboard
<li><a ui-sref="submodule1.dashboard">submodule1.dashboard</a></li>
All the other details check here