I have an application with one page called index.html. This page is the main page inside the application which I load my partials into.
Here is my Index.html:
<body>
<!--<div id="view" ng-view></div>-->
<div id="view" ui-view></div>
</body>
I want to load a Partial into this but then a partial into the partial i have just added.
The partial i want to add in is called dashboard.html and should be called when /dashboard routing is hit. Then I want to load a partial into the UI-View inside dashboard.html.
I don't know what other information I would need to supply to make this happen?
EDIT:
.state('dashboard', {
url: '/dashboard',
templateUrl: 'partials/dashboard.html',
controller: 'dashboard'
})
.state('dashboard.item', {
//url: '/dashboard/calender',
templateUrl: 'partials/calender.html',
controller: 'aceTrackerDash'
})
Its good to define nested states for this purpose . When the application is in a particular state — when a state is "active" — all of its ancestor states are implicitly active as well. Below, when the "contacts.list" state is active, the "contacts" state is implicitly active as well, because it's the parent state to "contacts.list" . So all nested defined views are loaded in their proper position:
Example :
$stateProvider
.state('contacts', {
templateUrl: 'contacts.html',
controller: function($scope){
$scope.contacts = [{ name: 'Alice' }, { name: 'Bob' }];
}
})
.state('contacts.list', {
templateUrl: 'contacts.list.html'
});
<!-- index.html -->
<body ng-controller="MainCtrl">
<div ui-view></div>
</body>
<!-- contacts.html -->
<h1>My Contacts</h1>
<div ui-view></div>
<!-- contacts.list.html -->
<ul>
<li ng-repeat="contact in contacts">
<a>{{contact.name}}</a>
</li>
</ul>
Plunker : http://plnkr.co/edit/7FD5Wf?p=preview
Also take a look at this :
Angular-UI Router: Nested Views Not Working
Related
I'm trying to use AngularJS + ui-router in my project, it is working tho but I am in the middle of a situation here...
I have a HOME state with url /, and that state needs to do the following:
When user is NOT logged in, I want to show a full page with a login form and some different index.html because I don't need some columns and stuff.
When the user IS logged, then the default index.html should be used so I can use my ui-view grid system with all the cool stuff when a user is logged (navbar, search forms and a lot more which are in index.html as they must be shown in every page).
In order to check if the user is logged I have a factory AuthFactory.isUserLogged()
This is what I have done but is not exactly what I want...
index.html
<div ng-cloak="" ng-if="$root.globals.currentUser">
<div class="ui fixed inverted menu">
<div class="ui container">
<a class="header item" href=""><img class="logo" src="">Dashboard</a>
<a class="item">Link</a>
<div class="right menu">
<div class="ui dropdown icon item">
{{ $root.me.username }}
<div class="menu">
Settings
<div class="divider"></div>
Logout
</div>
</div>
</div>
</div>
</div>
<div class="pusher">
<div class="full height">
<div class="ui main container" ui-view="mainContainer"></div>
</div>
</div>
</div>
<div ng-cloak="" ng-if="!$root.globals.currentUser" ui-view="mainContainer"></div>
As you can see, ui-view="mainContainer" is declared twice in the same index.html one for user logged and one when not ($root.globals.currentUser)
app.js
$stateProvider
.state('home', {
url: '/',
views: {
'mainContainer': {
templateUrl: 'views/main.html',
controller: 'HomeCtrl',
controllerAs: 'vm'
}
}
})
I know this isn't a good solution, that's why I am asking for a better one...
PS: It doesn't really matter which index.html I use, I just don't need whole markup in my not-logged-home, just a simple login form without navbar and stuff
EDIT:
This isn't working, even the console.log, it doesn't output anything
.state('home', {
url: '/',
views: {
'mainContainer': {
templateUrl: function (AuthFactory) {
if (AuthFactory.isUserLogged()) {
console.log("yep");
return 'views/main.html';
}
console.log("nope");
return 'views/login.html';
}
}
}
})
Make two different state for login and home. When user is not logged in call login state and after login home page. Only one on master page.
Then for later transition after login you need to define another on home html page.
$stateProvider
.state('login',
{
url: '/login',
templateUrl: "Account/Login.html",
controller: 'LoginController'
})
.state('home',
{
url: '/home',
templateUrl: "Home/Home.html",
controller: 'HomeController'
})
I am trying to utilize the Materialize Framework's Modal component along with Angularjs' ui-router module, but I'm having trouble trying to configure it properly.
Here's my $stateProvider definition
// Modal States ===============================
.state("modal", {
views:{
"modal": {
templateUrl: "resources/templates/modal.html"
}
},
abstract: true
})
.state("modal.modal1", {
views:{
"modal": {
templateUrl: "resources/templates/modals/modal-content-1.html"
}
}
})
And the `ui-view' definition on my index.html along with the trigger
<div ui-view="modal" autoscroll="false"></div>
What I'm trying to figure out is how to both render the modal and simultaneously switch to the modal1 state using the trigger on the Materialize button.
The init of the modal is simple enough:
<a class="waves-effect waves-light btn" href="#modal1">Modal</a>
<!-- Modal Structure -->
<div id="modal1" class="modal">
<div class="modal-content">
<h4>Modal Header</h4>
<p>A bunch of text</p>
</div>
<div class="modal-footer">
Agree
</div>
</div>
Any thoughts? Thanks much!
It seems that the state config you wrote is not correct, you have used the same named "modal" ui-view in both parent and child states.
Does your resources/templates/modal.html also contains a ui-view named "modal" ?
As your parent state is abstract, it can not be activated but for any child state to render, your parent state's template should have a ui-view.
Example below:
$stateProvider
.state('contacts', {
abstract: true,
url: '/contacts',
// Note: abstract still needs a ui-view for its children to populate.
// You can simply add it inline here.
template: '<ui-view/>'
})
.state('contacts.list', {
// url will become '/contacts/list'
url: '/list'
//...more
})
.state('contacts.detail', {
// url will become '/contacts/detail'
url: '/detail',
//...more
})
Reference: https://github.com/angular-ui/ui-router/wiki/nested-states-&-nested-views#abstract-state-usage-examples
I use ui-router to route to particular sub page as needed:
var myApp = angular.module("myApp",['ui.router']);
myApp.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('usergroups', {
url: "/usergroups",
templateUrl: "pages/usergroups.html",
controller : 'UsergroupsCtrl'
})
.state('usergroups.create', {
url: "/create",
templateUrl: "pages/usergroups.new.html",
controller : 'UsergroupsCtrl'
})
...
This is my usergroups.html:
<body>
<h3>User Groups</h3><br/>
<button class="fon-btn" type="button" ng-hide = "toAdd" ng-click="toAdd = true" ui-sref="usergroups.create">Create New Group</button>
<div ui-view></div>
<ul>
<li class="bitcard padding10" ng-repeat="group in usergroups">
<span class="padding10"><strong>{{group.name}}</strong></span>
</li>
</ul>
</body>
and usergroups.new.html:
<body>
<form ng-submit="add()">
<input class="btn" type="submit" value="Add Usergroup"><br/><br/>
</form>
</body>
When I click on Add Usergroup, it will called add() from UsergroupsCtrl:
$scope.add = function() {
$scope.usergroups.push({name:$scope.name});
console.log($scope.usergroups);
}
The console show that $scope.usergroups is already updated. but somehow in usergroups.html: ng-repeat="group in usergroups" did not update the view. I add $scope.$apply() and $scope.$digest() but got an error:
$apply already in progress
But everything works fine if I did not use ui-router. How can I resolve this?
I think same $scope cannot be used in two different controllers. you can change it to $rootScope. like $rootScope.usergroups.push(). This SO may help you. You can use $stateParam also.
I asked a question yesterday How to do multiple views with Angular to support header and sidebar? and based on that question I was able to make some progress in having a header and a sidebar for my AngularJS App.
I've got a working fiddle here: http://jsfiddle.net/mcVfK/929/
The JS looks like this:
angular.module('app', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/header1', {
templateUrl: 'header1.html',
controller: DashboardCtrl
})
.when('/header2', {
templateUrl: 'header2.html',
controller: DashboardCtrl
})
.when('/dashboard',{
templateUrl: 'dashboard.html',
controller: DashboardCtrl
})
.when('/sidebar1',{
templateUrl: 'sidebarlink1.html',
controller: DashboardCtrl
})
.when('/sidebar2',{
templateUrl: 'sidebarlink2.html',
controller: DashboardCtrl
})
.otherwise({
redirectTo: '/header1'
});
}]);
function DashboardCtrl() {
}
This seems to work, however, I want to find out whether there is a way to avoid including sidebar.html on every link in the sidebar?
If you notice on the fiddle, I'm doing this:
<script type="text/ng-template" id="sidebarlink1.html">
<div ng-include="'sidebar.html'" id="sidebar"></div>
sidebar link 1 content - including sidebar
</script>
<script type="text/ng-template" id="sidebarlink2.html">
<div ng-include="'sidebar.html'" id="sidebar"></div>
sidebar link 2 content - including sidebar
</script>
So I'm including sidebar.html on every link in the sidebar. I'm wondering if there is a way to avoid this? Also, is there an Angular way to highlight which sidebar link is currently active?
You can move the sidebar include out and use a variable to determine in what route you want to see it. Check out this jsfiddle:
http://jsfiddle.net/mcVfK/931/
angular.module('app', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when('/header1', {
templateUrl: 'header1.html',
controller: DashboardCtrl,
resolve: {
hasSidebar: function($rootScope) {
$rootScope.hasSidebar = false;
return false; }
}
})
I recomend to use ui-router (What is the difference between angular-route and angular-ui-router?) instead of ngRoute. Lear about it if you are interested. And then use some ng-switch like this:
//Parent template
<script type="text/ng-template" id="sidebarlinkparent.html">
<div ng-include="'sidebar.html'" id="sidebar"></div>
<div ng-switch="$state.current.name">
<div ng-switch-when="sidebar1" ng-include="'sidebarlink1.html'"></div>
<div ng-switch-when="sidebar2" ng-include="'sidebarlink2.html'"></div>
</div>
</script>
//template sidebar 1
<script type="text/ng-template" id="sidebarlink1.html">
sidebar link 1 content - including sidebar
</script>
//template sidebar 2
<script type="text/ng-template" id="sidebarlink2.html">
sidebar link 2 content - including sidebar
</script>
Then change your templateUrl in route config to go at the parent template sidebarlinkparent.html on /sidebar1 and /sidebar2
Aswell you can use your actual ngRoute and change the ngSwitch condition with a controller scope var setted on routes or something like that
EDIT:
OPTION 2:
//Parent template
<script type="text/ng-template" id="sidebarlinkparent.html">
<div ng-include="'sidebar.html'" id="sidebar"></div>
<div ng-include="$state.current.name +'.html'"></div>
</script>
OPTION 3:
//Parent template
<script type="text/ng-template" id="sidebarlinkparent.html">
<div ng-include="'sidebar.html'" id="sidebar"></div>
<div ng-include="$state.params.include +'.html'"></div>
</script>
etc etc..
Current
index.html
<body>
<div id="container" >
<div id="modal" >
</div>
<div class="wrapper mobileWrapper">
<!-- ui-view contains visible(window) of webpage -->
<div ui-view=""></div>
</div>
</div>
</body>
header.html
<header>
Header
</header>
footer.html
<footer>
Header
</footer>
mainPage.html - partial/template
<div ng-include="'header.html'"></div>
<div> Current Page Contents </div>
<div ng-include="'footer.html'"></div>
I need to keep only <div ui-view=""></div> inside index.html and need to move remaining tags somewhere inside.
In the above example if I used ng-include then tags opened in header.html needs to be closed in header only.
Is there any alternative ideas
Edit: I got one solution
Before I'm using
// Before main.html loading
angular.module 'ngApp'
.config ($stateProvider) ->
$stateProvider
.state 'home',
url: '/'
templateUrl: 'app/views/main/main.html'
controller: 'MainCtrl'
// Problem Solved: before wrapped with wrapper.html
angular.module 'ngApp'
.config ($stateProvider) ->
$stateProvider
.state 'wrapper',
abstract: true,
templateUrl: 'app/views/main/wrapper.html'
.state 'wrapper.home',
url: '/'
templateUrl: 'app/views/main/main.html'
controller: 'MainCtrl'
Is there any way to wrap some html for all views.
not in index.html
and
not in main.html(partial)
Edit 2:
Before my states like
.state 'home',
.state 'about-us',
to wrap html I created on abstract state
.state 'wrapper',
abstract: true,
templateUrl: 'app/views/main/wrapper.html'
then I prefixed parent state(wrapper) to all other states
.state 'wrapper.home',
.state 'wrapper.about-us',
Is there any way to do it without creating a parent state(wrapper)