Trying to switch between child views, however ui-sref generate a wrong url when the other child is already loaded.
The correct link: 'template/viewname.html'
The actual link: 'home/template/viewname.html'
How to stop ui-sref from adding 'home/' to the link ?
Thanks
app
angular.module('app',[,'ngRoute','ui.router']);
config
angular.module('app').config(['$urlRouterProvider', '$stateProvider', '$locationProvider', function ($urlRouterProvider, $stateProvider, $locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
});
$urlRouterProvider.otherwise('/');
$stateProvider.state('home', {
url: '/home',
templateUrl: 'template/index.html',
controller: 'contr'
})
.state('home.about', {
parent:'home',
url: '/about',
templateUrl: 'template/about.html',
controller: 'contr'
})
.state('home.contact', {
parent: 'home',
url: '/contact',
templateUrl: 'template/contact.html',
controller: 'contr'
}) }]);
Home page
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta charset="utf-8" />
</head>
<body>
<h3>Home</h3>
<div>
<a ui-sref="home.about">abouttt</a>
<a ui-sref="home.contact">contact</a>
</div>
<div ui-view>
</div>
</body>
</html>
You're shooting yourself in the foot:
you set requireBase to false, instead of using the default. The reason for the base tag is precisely that it allows relative URLs to be treated as relative to the base URL, rather than to the current URL
despite your choice to not use a base tag, you still use relative URLs, instead of absolute ones (i.e. URLs starting with `/, and which thus always point to the same location whatever the current location is).
See https://docs.angularjs.org/guide/$location#relative-links for more information.
just a small plnkr: http://plnkr.co/edit/RbjGt8zhAGSRb00idkEU?p=preview
var app = angular.module('plunker', ['ui.router'])
.config(['$stateProvider', '$urlRouterProvider','$locationProvider', function($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false
})
$stateProvider.state('home', {
url: '/home',
})
.state('home.about', {
parent:'home',
url: '/about',
views:{
'#':{
'templateUrl': '/tpl1.html'
}
}
//controller: 'contr'
})
I would recommend to use absolute URLs in your templateUrl, i.e. with a leading slash. For example:
$stateProvider.state('home', {
url: '/home',
templateUrl: '/template/index.html',
controller: 'contr'
});
Related
I am using $stateprovider to navigate between pages I had given $state.go('view1') to go to view1.html:
config(['$qProvider','$stateProvider','$locationProvider', '$routeProvider', function($qProvider,$stateProvider,$locationProvider, $routeProvider) {
$locationProvider.hashPrefix('!');
$stateProvider
.state('index', {
url: '/',
templateUrl: 'index.html'
})
.state('view1', {
url: '/view1',
templateUrl: 'view1/view1.html',
controller:'View1Ctrl'
})
.state('view2', {
url: '/view2',
templateUrl: 'view2/view2.html'
});
$routeProvider.otherwise({redirectTo: '/'});
$qProvider.errorOnUnhandledRejections(false);
}])
Function using $state:
controller("appcontroller",['$scope','$state','$stateParams',function($scope,$state,$stateParams,$rootScope){
$scope.login = function()
{
$state.go('view1');
}
}]);
Here view1.html is loading but it's showing above index.html.
As you are using Anguar ui-router. You must have kept in index.html. So your view1.html will be replaced there only. Other code in index.html will be untouched by your angular code.
<p> Here is me </p>
<ui-view></ui-view>
Now, if you change the route. "Here is me" will be always there.
Hope this was the issue what i understood.
My application is failing with the error in the title. This error is occurring when I define too many states for my ui-router. Previously when I posted this problem I was told that this is the same as the error discussed by the posting, “Angular “state already defined” error after running concat/uglify”. I changed my code as indicated by the post, wrapping it in a closure. After the change the code continued to act the same way. That is to say that with all of the defined states the code failed with stated error. When I reduced the number of states the code ran fine.
I have included the code below but I am only showing one state defined to minimize code. My current code has 40 states and I will more than double the number of states by the time the application is complete. Each state has 6 views. The commented code is what I was originally using. The uncommented code is what I believe was described as the solution in the previous post.
Appreciate if someone could provide suggestions for fixing this code or for better architecting the application if that is what I need to do.
(function (angular) {
angular
.module('app',['ngResource', 'ui.router','xeditable', 'inputDropdown'])
.config(function($logProvider, $stateProvider, $locationProvider, $urlRouterProvider ){
// var app = angular.module('app',['ngResource', 'ui.router','xeditable', 'inputDropdown']);
// angular.module('app').config(function($logProvider, $stateProvider, $locationProvider, $urlRouterProvider ){
$logProvider.debugEnabled(true);
var routeRoleChecks = {
admin: {auth: function(flAuth){
return flAuth.authorizeCurrentUserForRoute('admin')
}},
user: {auth: function(flAuth){
return flAuth.authorizeAuthenticatedUserForRoute()
}}
};
$locationProvider.html5Mode({
enabled: true,
requireBase: false, //required to specify base of application in our HTML
rewriteLinks: true //Angular will rewrite URLs as necessary (add# to older browsers)
});
$stateProvider
.state('home', {
url: '/',
views: {
'content-header': {
templateUrl: '/app/main/main-header',
controller: 'flMainCtrl',
caseInsensitiveMatch: true
},
'content-banner': {
templateUrl: '/app/main/main-carousel',
controller: 'flMainCtrl',
caseInsensitiveMatch: true
},
'content-main': {
templateUrl: '/app/games/game-searchList',
controller: 'flGameSearchButtonCtrl',
//controllerAs: 'games:id',
caseInsensitiveMatch: true
},
'content-left': {
templateUrl: '/app/games/game-menu-left',
controller: 'flGameSearchButtonCtrl',
//controllerAs: 'games:id',
caseInsensitiveMatch: true
},
'content-right': {
templateUrl: '/app/games/game-menu-right',
controller: 'flGameSearchButtonCtrl',
//controllerAs: 'games:id',
caseInsensitiveMatch: true
},
'content-footer': {
templateUrl: '/app/main/main-footer',
controller: 'flMainCtrl',
caseInsensitiveMatch: true
}
}
})
$urlRouterProvider.otherwise('home');
});
angular.module('app').run(function($rootScope, $location){
$rootScope.$on('$stateChangeError', function(evt, current, previous, rejection){
if (rejection === 'not authorized'){
$location.path('/');
}
});
});
})(window.angular);
Please try this example: this is working my example
include angularjs library:
<script src="assets/js/angularjs-min.js"></script>
<script src="assets/js/angular-ui-router.js"></script>
<script src="app/app.js"></script>
<script src="app/routes.js"></script>
add ng-app in your html body part:
<html lang="en" ng-app="myApp" ng-cloak=""></html>
app.js
var app = angular.module("myApp", ['ui.router']);
routes.js
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state("home", {
url: "/home",
templateUrl: './view/home.php',
controller: 'homeCtrl'
}).state("login", {
url: "/login",
templateUrl: './view/login.php',
controller: 'loginCtrl'
});
$urlRouterProvider.otherwise('home'); });
i am new Angular and trying to get a working example setup for Angular UI router
I researched some questions on stackoverflow but dont see the issue specifically. My Issue is that even though in browser debugging and network analysis i am seeing thatm my template html is called, still not seeing any content in browser.No errors in console
AngularJS ui-router - template not displaying
Using Angular 1.4.7 and corrosponding
Please find app.js below
(function(){
angular.module('TestPrj',['ui.router']);
angular.module('TestPrj').config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise('/ReportB');
$stateProvider
.state('a', {
url: '',
abstract:true,
controller:'mainController',
controllerAs:'main',
templateUrl: 'partials/home.html'
})
.state('a.b', {
url: '/ReportB',
controller:'B',
controllerAs:'B',
templateUrl: "partials/B.html"
});
});
angular.module('TestPrj').run(function($rootScope,$state){
$rootScope.$on("$stateChangeError", console.log.bind(console));
});
})();
Controller b.js :
(function(){
angular.module('TestPrj').controller('B',B);
function B($state){
this.pageName = "Report a B";
}
B.$inject = ["$state","$stateParams","$scope"];
})();
Controller main.js
(function(){
angular.module('TestPrj').controller('mainController',mainController);
function mainController($state,$translate){
}
mainController.$inject = ["$state","$translate"];
})();
index.html
<!DOCTYPE html>
<html>
<head ng-app="TestPrj" lang="en">
<script type="text/javascript" src="js/lib/angular.min.js"></script>
<script type="text/javascript" src="js/lib/angular-ui-router.min.js"></script>
<script type="text/javascript" src="js/lib/angular-translate.min.js"></script>
<script type="text/javascript" src="js/lib/angular-translate-loader-url.js"></script>
<script type="text/javascript" src="js/lib/ui-bootstrap-tpls-0.12.0.min.js"></script>
<script type="text/javascript" src="js/lib/ui-mask.min.js"></script>
<script type="text/javascript" src="js/app.js"></script>
<script type="text/javascript" src="js/controllers/claimTypeSelection.js"></script>
<script type="text/javascript" src="js/controllers/main.js"></script>
</head>
<body>
<div ui-view=""></div>
</body>
</html>
partials/home.html
<div class="container">
<div ui-view=""></div>
</div>
partials/B.html
<div>
<div ui-view=""></div>
<h1>This is a Heading</h1>
<p>This is a paragraph.</p>
</div>
Also sharing screenshot of my project setup
Angular Setup
Based off the digging I did I think the issue is that you made the first state abstract. There is an issue posted on the github for ui-router you can read here. Also, consider the two plunkr examples
without abstract
$stateProvider
.state('route1', {
url: "/route1",
templateUrl: "route1.html"
})
.state('route1.list', {
url: "/list",
templateUrl: "route1.list.html",
controller: function($scope){
$scope.items = ["A", "List", "Of", "Items"];
}
})
.state('route2', {
url: "/route2",
templateUrl: "route2.html"
})
.state('route2.list', {
url: "/list",
templateUrl: "route2.list.html",
controller: function($scope){
$scope.things = ["A", "Set", "Of", "Things"];
}
})
})
with abstract
$stateProvider
.state('route1', {
url: "/route1",
abstract: true,
templateUrl: "route1.html"
})
.state('route1.list', {
url: "/list",
templateUrl: "route1.list.html",
controller: function($scope){
$scope.items = ["A", "List", "Of", "Items"];
}
})
.state('route2', {
url: "/route2",
templateUrl: "route2.html"
})
.state('route2.list', {
url: "/list",
templateUrl: "route2.list.html",
controller: function($scope){
$scope.things = ["A", "Set", "Of", "Things"];
}
})
})
The second plunkr is a copy of the first except that abstract: true was added to the state and now it doesn't work.
Also, make sure you either clear your browser cache frequently or disable caching while using ui-router. It's pretty bad about serving cached results.
It isn't clear why you are using an abstract state. The abstract state can provide data and enter/exit processing to child states. But it isn't activated. It does need a template.
https://github.com/angular-ui/ui-router/wiki/Nested-States-and-Nested-Views#abstract-states
In your example the child state does done of these and the abstract state was apparently meant to be used.
It would seem you didn't intend to make it abstract.
Update: The abstract url can't be blank. This is an example of your code with the url set:
.state('a', {
url: '/a',
abstract: true,
controller: 'mainController',
controllerAs: 'main',
templateUrl: 'partials/home.html'
})
http://plnkr.co/edit/11o6qF?p=preview
To see the functionality use this link: http://run.plnkr.co/CUN147Z4YdCKRxRw/#/a/b
I'm using ui-router for state handling. This works fine, but now I have to create page 404 and would like to display it on the whole page and not inside the page as other pages.
app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider',
function ($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.hashPrefix('!').html5Mode({
enabled: true,
requireBase: false
});
$stateProvider
.state('stateIndex', {
url: '/',
templateUrl: '/templates/list.html',
controller: 'dashListController'
})
.state('stateList', {
url: '/list',
templateUrl: '/templates/list.html',
controller: 'dashListController'
}).state('stateDashboard', {
url: '/dashboard/:id',
templateUrl: '/templates/dashboard.html',
controller: 'dashboardController'
})
.state('stateWidgetsList', {
url: '/widgetsList',
templateUrl: '/templates/widgetsList.html',
controller: 'widgetsListController'
})
.state('404', {
url: '/404',
templateUrl: '/templates/404.html'
});
}]);
and on my index.html I have
<div ui-view></div>
where I display all the pages, outside of this I have logo, menu, etc.. which I would like to hide while displaying 404 page.
How can I do it?
Personally I would redesign the index.html, and bring the outer template (logo, menu, etc), into it's own template and state. Then you can sit child states below it in the ui-router hierarchy. For example:
$stateProvider
.state('app', {
abstract: true,
url: '',
templateUrl: '/templates/appcontainer.html'
})
.state('app.stateIndex', {
url: '/',
templateUrl: '/templates/list.html',
controller: 'dashListController'
})
.state('404', {
url: '/404',
templateUrl: '/templates/404.html'
});
Then you just need to put your logos/menus, etc inside appcontainer.html, and then just have a single <div ui-view></div> inside your index.html. Also if you do it this way, don't forget to add the child ui-view inside appcontainer.html.
You can create a root parent state that will contain your layout stuff (logo, menu, etc) and have the 404 live outside of that.
routes
$stateProvider
.state('root', {
abstract: true, // makes this state not directly accessible
templateUrl: 'root.html'
})
.state('root.stateIndex', {
url: '/',
templateUrl: '/templates/list.html',
controller: 'dashListController'
})
// ...
.state('404', {
url: '/404',
templateUrl: '/templates/404.html'
});
root.html
<nav><!-- menu stuff --></nav>
<ui-view></ui-view>
<footer></footer>
EDIT : Here is a plunker
I'm a bit disappointed about the issue I have with ui-router as it is a very basic use.
I have an "empty" html index file that welcomes ui-views. I created 2 main templates : application.html and public.html . Basically they have 2 different headers/footers.
index.html
<div ui-view="">
<!-- encapsulate app/public -->
<a ui-sref="app">app</a>
</div>
app-routes.js
var myApp = angular.module('taApp', ['ui.router','ui.bootstrap','ui.sortable', 'ngResource']);
myApp.config(function($stateProvider, $urlRouterProvider) {
//
// For any unmatched url, redirect to /auth
$urlRouterProvider.when("", "/auth");
$urlRouterProvider.when("/", "/auth");
$urlRouterProvider.otherwise("/auth");
$stateProvider
.state('public', {
url:'',
abstract: true,
templateUrl: 'public.html',
/*views: {
'topbar': { template: 'public.topbar' },
'login': { template: 'public.login' }
}*/
})
.state('auth', {
url: '/auth',
templateUrl: '/partials/login/loginCard.html'
})
/*** LOGGED STATES ***/
//login
.state('app', {
templateUrl: 'application.html',
controller: 'authCtrl',
url: '/app'
})
});
Notice: the ui-sref state doesn't work too as it should load 'app' state.
Also I tried to force ui-view="app" or "public" without any success
I use angular-ui-router package on gulp.
There is something I missed and can't figure out.
Based on the updated question, related to this plunker, I updated that and make it working.
Fistly, angular must be loaded first
<script src="script.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>
we need this
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.15/angular-ui-router.min.js"></script>
<script src="script.js"></script>
And also, because our application "taApp" is defined:
var myApp = angular.module('taApp',
[
'ui.router' //,'ui.bootstrap','ui.sortable', 'ngResource'
]);
we have add that into index.html
<!DOCTYPE html>
<html ng-app="taApp">
And as we can see, because we are not having references to other module (inside of index.thml) I had to comment them out
'ui.router' //,'ui.bootstrap','ui.sortable', 'ngResource'
But once their code will be added to the page... it will work with them. So, this example is no working here
There is a working plunker
I guess that the public state, marked as abstract should be parent of all states. So we need to adjust state def like this:
$stateProvider
.state('public', {
url: '',
abstract: true,
templateUrl: 'public.html',
/*views: {
'topbar': { template: 'public.topbar' },
'login': { template: 'public.login' }
}*/
})
.state('auth', {
parent: 'public',
url: '/auth',
templateUrl: 'partials/login/loginCard.html'
})
/*** LOGGED STATES ***/
//login
.state('app', {
parent: 'public',
templateUrl: 'application.html',
controller: 'authCtrl',
url: '/app'
})
Any child state is inserting its view into parent - by default. So we must be sure, that the parent template public.html contains
<div ui-view=""></div>
There are other ways, but this is the most simple scenario