Angular UI-Router nested views - javascript

I am trying to get nested views to work in which after logging in it sends you to in.html from there all links link to a ui-view within in.html. Currently all links go to a "new" page
index.html
<!-- more HTML -->
<body ng-controller="MainController as main">
<!--<div id="loading"><span>Loading</span></div>-->
<div ui-view="default"></div>
</body>
<!-- more HTML -->
in.html
<a ui-sref="online">Online Users</a>
<div ui-view="main"></div>
app.js routes
var $td = $config.TPL_DIR;
$stateProvider
.state('auth', {
url: '/auth',
views: {
"default": {
controller: 'AuthController as auth',
templateUrl: $td + 'login.html'
}
}
})
.state('loggedin', {
url: '/in',
views: {
"default": {
templateUrl: $td + 'in.html'
}
}
})
.state('online', {
url: '/online',
views: {
"main": {
controller: 'OnlineController as online',
templateUrl: $td + 'online.html'
}
}
});

Try making some subviews and then changing the ui-view from in there. Something like
.state('loggedin.another_view', {
url: '',
views: {
"main": {
templateUrl: $td + 'partial.html'
}
}
})
Since loggedin is the parent view, when the router looks for main, it will look within the loggedin context for the view. It will load partial.html into your view.

Changed state to loggedin.online
.state('loggedin.online', {
url: '/online',
views: {
"main": {
controller: 'OnlineController as online',
templateUrl: $td + 'online.html'
}
}
});
Change link to
<a ui-sref=".online">Online Users</a>
<div ui-view="main"></div>

Related

angularjs named ui-views updating just one ui-view

I'm using AngularJS 1.5.8 and the ui-router and I have a menu on the left and a content area on the right.
I want the ability to navigate through the menu system without updating the 'content' ui-view, is that possible?
In my index.html I have these two ui-views
<div ui-view="menu"></div>
<div class="content" ui-view="content"></div>
Then in my settings route file I have the following;
settingsRoute = function($stateProvider, $urlRouterProvider){
$stateProvider
.state('settings', {
url: '/settings',
views: {
"menu": {templateUrl: 'templates/settings.html'}
}
})
.state('account', {
url: "/account",
views: {
"menu": {templateUrl: 'templates/settings.html'},
"content": {
templateUrl: 'templates/account.html',
controller: 'account'
}
}
});
$urlRouterProvider.otherwise('/account');
}
In my costings route file I have
costingsRoute = function($stateProvider){
$stateProvider
.state('costings', {
url: '/costings',
views: {
"menu": {templateUrl: 'templates/costings.html'}
}
})
.state('invoices', {
url: '/invoices',
views: {
"menu": {templateUrl: 'templates/costings.html'},
"content": {
templateUrl: 'templates/invoices.html'
}
}
})
}
angular.module('app').config(costingsRoute);
For example in the following demo when it loads it loads with the account body displayed in the content, when I click on 'costings' I would like that to only change the menu and leave the content view with whatever is in the content view, this could be 'account body' or 'profile body'.
https://plnkr.co/f7A773GJdu3NWy3Lg2eK
add this to your costing view...
https://plnkr.co/edit/Q2nXXWpSywkdEUKIUmC0?p=preview
.state('costings', {
url: '/costings',
views: {
"menu": {templateUrl: 'costings.html'},
"content": {
templateUrl: 'account.html'
}
}
})

How to make nested views on multiple views in angular ui router?

My app is very simple. i have a home page that contains header and body. in body section I want to show login page and if URL changed to 'password/forget' I show password reset form. my templates:
index.html :
<header ui-view="header">
</header>
<div class="container-fluid">
<div class="row">
<div ui-view="main">
</div>
</div>
</div>
home.html:
<div ui-view>
</div>
And ui-router config is this:
$locationProvider.html5Mode({enabled: true, requireBase: false});
$stateProvider.state('home', {
url: '/',
views: {
'header': {
templateUrl: '/header.html'
},
'main': {
templateUrl: '/home.html'
}
}
}).state('home.forgetPassword', {
url: '/password/forget',
templateUrl: '/forgetPassword.html',
});
Now when I go "/password/forget" anything happen and index.html is showing.
I want to show forgetPassword.html when route changes to "/password/forget" .
Following this code in documentation of ui-router:
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('state1', {
url: "/state1",
templateUrl: "partials/state1.html"
})
.state('state1.list', {
url: "/list",
templateUrl: "partials/state1.list.html",
controller: function($scope) {
$scope.items = ["A", "List", "Of", "Items"];
}
})
.state('state2', {
url: "/state2",
templateUrl: "partials/state2.html"
})
.state('state2.list', {
url: "/list",
templateUrl: "partials/state2.list.html",
controller: function($scope) {
$scope.things = ["A", "Set", "Of", "Things"];
}
});
});
What i suggest is to create the 'password' state first.
Try the following solution:
$stateProvider.state('home', {
url: '/',
views: {
'header': {
templateUrl: '/header.html'
},
'main': {
templateUrl: '/home.html'
}
}
}).state('password', {
url: '/password',
templateUrl: '/password.html',
}).state('password.forgetPassword', {
url: '/forget',
templateUrl: '/forgetPassword.html',
});
Create the file 'password.html' for now, later on it might be useful for '/password' view.
Problem solved. it was for / in parent state and repeat it on child states.

How to properly display header/footer using angularjs and ui-router?

This is my index.html:
<body>
<div ui-view></div>
</body>
This is my app.js:
angular.module('sample', [
'auth0',
'ngRoute',
'sample.home',
'sample.header',
'sample.login',
'ui.router',
'angular-storage',
'angular-jwt'
])
.config(function myAppConfig($stateProvider, $urlRouterProvider, $routeProvider, authProvider, $httpProvider, $locationProvider,
jwtInterceptorProvider) {
$stateProvider
.state('login', {
url: '/login',
templateUrl: 'login/login.html',
controller: 'LoginCtrl'
}).state('root', {
url: '/',
abstract: true,
views: {
'header': {
templateUrl: 'home/header.html',
controller: 'HeaderCtrl'
},
'footer': {
templateUrl: 'home/footer.html'
}
},
data: {
requiresLogin: true
}
}).state('root.home', {
url: '/',
views: {
'#': {
templateUrl: 'home/home.html'
}
},
data: {
requiresLogin: true
}
})
$urlRouterProvider.otherwise('/');
authProvider.init({
domain: AUTH0_DOMAIN,
clientID: AUTH0_CLIENT_ID,
loginUrl: '/login'
});
jwtInterceptorProvider.tokenGetter = function(store) {
return store.get('token');
}
$httpProvider.interceptors.push('jwtInterceptor');
})
.run(function($rootScope, auth, store, jwtHelper, $location, $state, $stateParams) {
$rootScope.$on('$locationChangeStart', function() {
if (!auth.isAuthenticated) {
var token = store.get('token');
if (token) {
if (!jwtHelper.isTokenExpired(token)) {
auth.authenticate(store.get('profile'), token);
} else {
$location.path('/login');
}
}
}
});
})
.controller('AppCtrl', function AppCtrl($scope, $location) {
$scope.$on('$routeChangeSuccess', function(e, nextRoute) {
if (nextRoute.$$route && angular.isDefined(nextRoute.$$route.pageTitle)) {
$scope.pageTitle = nextRoute.$$route.pageTitle + ' | Auth0 Sample';
}
});
})
If I do login & the root that's commented out, everything works fine. But I need to put in a header and footer (the files are correct) and when I try the root + root.home, I get a blank screen with no errors on the browser's console either.
I'm trying to go off of a few examples from online (such as this one) but none are working out so I don't know what I'm doing wrong.
Right now my header/footer.html just say header/footer.html while home has a button on it.
Added the full app.js in case that helps. Each html (footer/header/home) just has
<h1>Home</h1>
<div ui-view></div>
Edit: index.html
<body>
<div ui-view="header"></div>
<div ui-view></div>
<div ui-view="footer"></div>
</body>
app.js
.state('root.home', {
url: '/',
views: {
'#': {
templateUrl: 'views/home.html',
controller: 'HomeCtrl'
}
},
data: {
requiresLogin: true
}
})
I believe your issue here is your route is looking for a view named container not a class.
<div ui-view="container"></div>
Since it can't find a view named that it does not insert anything in the view.
Or you can just change your view route to be:
views: {
'#': {
templateUrl: 'home/home.html'
}
Which will tell it to insert that HTML in the first unnamed view it finds.
You can find a break down of how nested views work with UI-Router here
Assuming your home.html looks like this:
<div ui-view="header"></div>
<div ui-view="footer"></div>
your route should be something like
views: {
'header#home': {
templateUrl: 'home/header.html',
controller: 'HeaderCtrl'
},
'footer#home': {
templateUrl: 'home/footer.html'
}
},
data: {
requiresLogin: true
}

Angular ui-router not extending parent view

I am trying to extend a parent view to a child view.
My route.js
let view = {
'': {
templateUrl: '/app/content.html'
},
'sidebar': {
templateUrl: '/app/sidebar.html'
}
};
.state('profile', {
abstract: true,
url: '/profile',
views: view,
templateUrl: '/app/profile/profile.html'
})
.state('profile.about', {
parent: 'profile',
url: '/about',
views: {
'': {
templateUrl: '/app/profile/about.html'
}
}
})
My index.html:
<div ui-view></div>
My profile/profile.html:
//all other stuff (header, sidebar, etc)
<div>
<h1>Profile</h1>
<div ui-view=""></div>
</div>
My profile/about.html:
<div>
<h1>About</h1>
</div>
Everything works perfectly including the sidebar.
The problem is that about.html is showing the page but it is not extending the profile/profile.html page.
Any solutions?
Here is the plunker.
It's a little bit different but it is the same, considering how the route1 is not shown but the test.html is show.
Try this way:
let view = {
'': {
templateUrl: '/app/profile/index.html'
},
'content': {
templateUrl: '/app/content.html'
},
'sidebar': {
templateUrl: '/app/sidebar.html'
}
};
.state('profile', {
abstract: true,
url: '/profile',
views: view
})
.state('profile.about', {
parent: 'profile',
url: '/about',
views: {
'': {
templateUrl: '/app/profile/about.html'
}
}
})

angular-ui-router nested views

I have an app with 3 views (A,B,C) and 2 states(1,2)
html
<div ui-view="A"></div>
<div ui-view="B"></div>
<div ui-view="C"></div>
The two states are called list and create. In both states the template and controller of view A + B stay the same but view c should change templates and controllers. I can get view c's content to change but it refreshes view A and view B as it does ie things that are in their controllers run again.
What is the correct way to organise the router to prevent this?
js so far
$urlRouterProvider.otherwise("/basestate/list");
$stateProvider
.state('baseState', function() {
url:"/basestate",
templateUrl: "basestate.html",
controller: 'BaseStateCtrl'
})
.state('baseState.list', function() {
url: "/list",
views: {
"viewA#baseState": {
templateUrl: "viewA.html"
controller: "ViewACtrl"
},
"viewB#baseState": {
templateUrl: "viewB.html"
controller: "ViewBCtrl"
},
"viewC#baseState": {
templateUrl: "list.html"
controller: "listCtrl"
}
}
})
.state('baseState.create', function() {
url: "/create",
views: {
"viewA#baseState": {
templateUrl: "viewA.html"
controller: "ViewACtrl"
},
"viewB#baseState": {
templateUrl: "viewB.html"
controller: "ViewBCtrl"
},
"viewC#baseState": {
templateUrl: "create.html"
controller: "createCtrl"
}
}
})
To achieve that you basically need to freeze your viewA and viewC at the level of baseState and make that state abstract:
.state('basestate', {
url: '/basestate',
abstract: true,
views: {
"viewA": {
templateUrl: "viewA.html",
controller: "ViewACtrl"
},
"viewB": {
templateUrl: "viewB.html",
controller: "ViewBCtrl"
},
"viewC": {
template: '<div ui-view="viewC_child"></div>'
}
}
})
Note that for viewC we are making a placeholder that will contain our nested view (either list or create):
.state('basestate.list',{
url: "/list",
views: {
"viewC_child": {
templateUrl: "list.html",
controller: "ListCtrl"
}
}
})
.state('basestate.create', {
url: "/create",
views: {
"viewC_child": {
templateUrl: "create.html",
controller: "CreateCtrl"
}
}
})
Check this plunkr and be careful with commas in your code :)

Categories

Resources