ui-view inside another not showing - javascript

I have a question regarding Angular UI-Router and its ui-views. I declare three ui-views inside another one, and the only one that shows up is the one with the name "languages". I don't understand why this happens, and if anybody could help that would be great.
index.html:
<div ui-view="languages">
<div ui-view="dashboard"></div>
<div ui-view="partners"></div>
<div ui-view="footer"></div>
</div>
routes.js:
angular.module('TMHM')
.config(routeConfig);
routeConfig.$inject = ['$stateProvider', '$urlRouterProvider'];
function routeConfig ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('home', {
url: '/',
views: {
'languages': {
templateUrl: 'views/languages/languages.html'
},
'dashboard': {
templateUrl: 'views/dashboard/dashboard.html'
},
'partners': {
templateUrl: 'views/partners/partners.html'
},
'footer': {
templateUrl: 'views/footer/footer.html'
}
}
});
$urlRouterProvider.otherwise('/');
};
Here's the Plunker code, although I couldn't get that to work:
https://plnkr.co/edit/z8cFGHKVQNN623QbBUqi

There is updated and working plunker https://plnkr.co/edit/vKOr2yLUfaAfwoGyK0ws?p=preview
I created new routes.html, with this content
<h1>Routes</h1>
<hr />
<div ui-view="languages"></div>
<div ui-view="dashboard"></div>
<div ui-view="partners"></div>
<div ui-view="footer"></div>
And changed index.html to contain
<div ui-view=""></div>
And then state adjustment is:
.state('home', {
url: '/',
views: {
'': {
templateUrl: 'routes.html'
},
'languages#home': {
templateUrl: 'languages.html'
},
'dashboard#home': {
templateUrl: 'dashboard.html'
},
'partners#home': {
templateUrl: 'partners.html'
},
'footer#home': {
templateUrl: 'footer.html'
}
}
});
Also, essential was move the ng-app from <head> to <html> element
<html ng-app="TMHM">
<head >
check it here
More details and examples about named and multi views:
Nested states or views for layout with leftbar in ui-router?
Angular UI Router - Nested States with multiple layouts

I've never seen that done this way before (a routed view in a routed view). That may be because it doesn't work, or I've just never run into it, I don't know. I tend to think of views as being top level, and then includes as being the nested content.
If that's the idea, I've done something very similar to this, but I used ng-include (I currently have this in production in an app serving a lot of users):
<div ng-include="mycontroller.pathToFileIWantToShow"></div>
// alternatively, although hardcoding can be evil...
<div ng-include="path/to/some/file.html"></div>
This allows me to change the content dynamically, use binding etc. etc, and each included template can reference its own controller, or just use the controller that wraps it. It doesn't seem to matter how many I nest.

Related

Multiple views to nested state

I am using ui-router and I try to create several views inside one of my nested states.
In my logic, all of the views should be visible whenever the parent state is active.
I have read the wiki page on multiple named views multiple times, but could not get anything working yet.
My state template would show up, but my views never do.
Here is a working plunker
(You have to click on "Followers" in the navbar for the view to show up. Haven't figured why yet).
Important parts are the config
app.config([
'$stateProvider',
'$urlRouterProvider',
function ($stateProvider, $urlRouterProvider){
$stateProvider
.state('dashboard', {
url: '/dashboard',
templateUrl: 'dashboard.html',
controller: 'DashboardCtrl',
authenticate: true
}).state('dashboard.followers', {
url: '/followers',
templateUrl: 'dashboard.followers.html',
controller: 'DFollowersCtrl',
authenticate: true
}).state('dashboard.followers.add', {
views: {
'add': {
templateUrl: 'dashboard.followers.add.html',
controller: 'DFollowersAddCtrl',
authenticate: true
}
},
});
$urlRouterProvider.otherwise('dashboard');
}
]);
The main dashboard template (level 2, using a generic ui-view)
<div class="col-sm-9 col-sm-offset-3 col-md-10 col-md-offset-2 main">
<div class="flash-area">
<flash-message duration="2000" show-close="true"></flash-message>
</div>
<ui-view></ui-view>
</div>
and the dashobard.followers specific level 3 view, that has a specific name
<div>
<h1 class="page-header">Followers</h1>
<div ui-view="add"></div>
</div>
The trick is coming from, I think, a combination of :
I want to use level 3 nesting
Level 2 uses a generic ui-view, because it may contains my dashboard or something else.
Level 3 contains specific views, as it is where I want to use "views" and not "states" (as far as I understood, at least).
The final aim is to have more than one view in my template, but for now I reduced the attempts to only show the 'add' view.
I have seen several similar questions on SO already, such as this one or this other one but so far my attempts have not been fruitful.
I can access my "add" view directly if I reach its URL (when I try setting one)
But the dashboard.followers state does not get populated by the views.
I think there are several mistakes here you made:
if you want the url of dashboard.followers state and dashboard.followers.add state to be same, the child state dashboard.followers.add does not need the url option
probably can be a mistake(I am not sure because no code is provided), if you don't use the
views: { ... }
named views, but just directly use
url: '/followers',
templateUrl: '/partials/dashboard.followers.html'
angular just assume you want to insert the template in an unnamed <div ui-view></div> in the parents state's template not the root template. for example, in my example code, for state dashboard.followers, since it is a child state of dashboard, if I want to insert the template in root html template, I have to use
views: {
'#': {
template: '<div><h1 class="page-header">Followers</h1><a ui-sref="dashboard.followers.add">add</a><div ui-view="add"></div></div>'
}
}
/* myApp module */
var myApp = angular.module('myApp', ['ui.router'])
.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('landing', {
url: '/',
template: '<p>landing</p><a ui-sref="dashboard">dashboard</a>'
})
.state('dashboard', {
url: '/dashboard',
template: '<p>landing</p><a ui-sref="dashboard.followers">followers</a>'
})
.state('dashboard.followers', {
url: '/followers',
views: {
'#': {
template: '<div><h1 class="page-header">Followers</h1><a ui-sref="dashboard.followers.add">add</a><div ui-view="add"></div></div>'
}
}
})
.state('dashboard.followers.add', {
views: {
'add': {
template: '<p>followers</p>'
}
}
});
}])
.controller('MyAppCtrl', function($scope, $state /*, $stateParams*/ ) {
$state.go("landing");
});
<body ng-app="myApp" ng-controller="MyAppCtrl">
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.18/angular-ui-router.js"></script>
<div ui-view></div>
</body>
update
I made two plunkers to fit two different situation:
if you want to dynamically load add state to ui-view="add" by a
link, check
this out.
if you just want a sub template to be loaded always on dashboard.followers state, simply remove add states, and use views: {...} to load the add template in. here is the plunker.

angularjs ui router : nested views and nested states

I'm new to angular and I'm trying to understand nested views concept.
Based on the example provided in their documentation: https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
//home.html
<body>
<div ui-view="header"></div>
<div ui-view="settings"></div>
<div ui-view="content"></div>
</body>
I have settings.html which has a check box. If it's checked it will load in the view(not named) the advanced settings template if not it will load the basic template
//settings.html
<input type="checkbox" ng-change="change()" ng-model="advancedSettings" />
<div ui-view></div>
so far I have defined something like this:
$stateProvider
.state('home', {
views: {
'header': {},
'settings': {
templateUrl: 'settings.html'
},
'content': {},
}
})
since I have 2 templates basicSettings.html and advancedSettings.html that I need to load in the view from settings.html based on that checkbox, I thought I have to declare something like this:
.state('settings#home.basic',(){
templateUrl: 'basicSettings.html'
});
but it's not working, instead I receive a lot of errors on console. How is the best way to implement this, without removing names from homepage views(header,settings,content), also how do I change the view based on the check box?
Thanks
There is a working plunker
Solution here could be with states defined like this:
$stateProvider
.state('home', {
abstract: true,
url: "/home",
views: {
'header': {
template: "This is HEADER"
},
'settings': {
templateUrl: 'settings.html',
controller: 'HomeCtrl',
},
'content': {
template: "This is CONTENT"
},
}
})
.state('home.basic', {
url: "/basic",
templateUrl: 'basicSettings.html'
})
.state('home.advanced', {
url: "/advanced",
templateUrl: 'advancedSettings.html'
})
we have parent state "home" and two children. These are triggered on change by 'HomeCtrl', e.g. like this:
.controller('HomeCtrl', ['$scope', '$state',
function($scope, $state) {
$scope.advancedSettings = false;
$scope.change = function(){
var childState = $scope.advancedSettings
? "home.advanced"
: "home.basic";
$state.go(childState);
}
}])
So, based on the setting, the view target "settings" and its ui-view="" (unnamed one) is filled with a child state - basic or advanced
Check it here

AngularJS - Loading named views within child states ( not abstract )

Alright so I am having an issue with my named views loading content into my state.
Its mostly problematic because I really do not know why it isnt working; with angular that usually means a typo but I have recreated my problem in a plunker and am getting the same results so maybe I am missing something.
I know this question has been asked before:: however in all the results I saw on here people were putting content into an abstract state's children. what I want to do is have a state; populate it with named views as well as other content relevant to that state; then have that states children load content into the main states named views. should be simple enough and rather straight forward but alas mine will not work for me.
Here is the link to the plunker made:: http://plnkr.co/edit/TWCQuoIyJRvTb42Z7xxe?p=preview
as you will see the main 'papers' state is loading. however none of the content from the named views is being loaded into the 'papers' state from its child state 'papers.views'.
Code for reference:
Module declaration and state config(app.js)
var app = angular.module( 'app', [ 'ui.router' ] );
app.config(['$stateProvider', '$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('/papers');
// States
$stateProvider
.state( 'papers', {
url: "/papers",
templateUrl: 'papers.html'
}) // nested paper state + views
.state( 'papers.views', {
views: {
'#papers': {
templateUrl: 'papers.home.html'
},
'paper1#papers': {
templateUrl: 'papers.paper1.html'
},
'paper2#papers': {
templateUrl: 'papers.paper2.html'
}
}
})
}
])
.run(['$rootScope', '$state', '$stateParams',
function ($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
}])
Index page (papers.html loading here):
<body>
<div ui-view></div>
</body>
papers page ( where nested views are supposed to be loading )
<h1>This is the papers page. other views should load in here</h1>
<div ui-view ></div>
<div ui-view="paper1" ></div>
<div ui-view="paper2" ></div>
One way, how to fix this is to add two lines:
change your parent to be abstract : true and
force child to define url : ''
There is an upated and working plunker, this is the updated state def:
$urlRouterProvider.otherwise('/papers');
// States
$stateProvider
.state( 'papers', {
// NEW LINE
abstract: true,
url: "/papers",
templateUrl: 'papers.html'
}) // nested paper state + views
.state( 'papers.views', {
// NEW LINE - because parent is abstract, same url here - this will be loaded
url: '',
views: {
'#papers': {
templateUrl: 'papers.home.html'
},
'paper1#papers': {
templateUrl: 'papers.paper1.html'
},
'paper2#papers': {
templateUrl: 'papers.paper2.html'
}
}
})
More details about this in documentation:
How to: Set up a default/index child state
Check it here
Another way could be to change the default:
$urlRouterProvider.otherwise('/papers/view');
And add url: '/view' to child state:
...
.state( 'papers.views', {
url: '/view',
views: {
...
Check this version here

Angular.js - ui-router not injecting view

I have a problem with ui-router for angular.js.
I am currently working on a project with angular.js and using ui-router as router.
The problem now is, that I want to have a nested view as like this:
views/settings/index.html (also an previously created template in ui-router)
<div class="settings">
[...]
<div class="settings-content" ui-view="content"></div>
</div>
app.js
$stateProvider.state('settings', {
url: '/settings',
views: {
main: {
templateUrl: 'views/settings/index.html',
controller: 'SettingsController'
},
"content": {
templateUrl: 'views/settings/privacy.html',
controller: 'SettingsController'
}
},
ncyBreadcrumb: { label: 'Settings' }
})
Now the problem I have is, that the defined content template is not injected into the ui-view="content" div. The main content (views/settings/index.html) is loading properly. And in nested states it's also possible to add a template into the ui-view="content" with the same "string": Object.
How does this come?
Thanks in advance!
You must use the viewName#stateName syntax as stated here.
Try this
$stateProvider.state('settings', {
url: '/settings',
views: {
main: {
templateUrl: 'views/settings/index.html',
controller: 'SettingsController'
},
"content#settings": {
templateUrl: 'views/settings/privacy.html',
controller: 'SettingsController'
}
},
ncyBreadcrumb: { label: 'Settings' }
})
I have used the ui-router module in my demo application.
You need to specify the hierarchy in your view.
The parent view is not specified to child view so you must use ViewName#parentState
https://github.com/singhmohancs/angularDemo/tree/master/app/modules

Angular ui-router nested view

Im trying to inject a nested view into my normal view, using ui-router.
I know it's possible by doing ng-include. But I want to solve it by using ui-router.
My html is as follow:
<div class="row">
<div class="col-md-12">
<div class="panel panel-default">
<div class="panel-heading">Project todos</div>
<div class="panel-body">
<div ui-view="todos"></div>
</div>
</div>
</div>
</div>
Then in my script I got a state:
.state('project', {
url: '/project/:projectId',
templateUrl: 'views/project/project.html',
controller: 'ProjectCtrl',
views: {
'todos': {
templateUrl: 'views/project/todos.html'
}
}
})
Update - isn't there something like this possible?
.state('project', {
url: '/project/:projectId',
templateUrl: 'views/project/project.html',
controller: 'ProjectCtrl',
views: {
'todos#project': {
templateUrl: 'views/project/todos.html'
}
}
})
Anyone can find a typo or something? I've read the docs. I am not sure what's wrong.
Thanks in advance!
There is a working plunker, showing how we can make it running
On the index.htm we need to have the <div ui-view="" ></div>, which is the place were we inject the project.html. Then we adjust the state definition, to inject also nested view - using ui-view absolute naming:
.state('project', {
url: '/project/:projectId',
views: {
'' : {
templateUrl: 'views.project.project.html',
controller: 'ProjectCtrl',
},
'todos#project': {
templateUrl: 'views.project.todos.html'
}
}
});
The absolute name todos#project, will inject the todos.html into the project.html. Check the plunker
See the:
View Names - Relative vs. Absolute Names
A cite:
...Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname#statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax...

Categories

Resources