There is my router.js
$stateProvider.state("workarea", {
url: "/",
templateUrl: "/templates/workarea.html",
requireLogin: true
}).state("workarea.shared", {
url: "/workarea",
controller: "workareaSharedCtrl",
requireLogin: true,
views: {
"options": {
templateUrl: "/views/options.html"
},
"workspace": {
templateUrl: "/views/workspace.html"
}
}
}).state("workarea.user", {
url: "/:username",
controller: "workareaUserCtrl",
requireLogin: true,
views: {
"options": {
templateUrl: "/views/options.html"
},
"workspace": {
templateUrl: "/views/workspace.html"
},
"comments": {
templateUrl: "/views/comments.html"
}
}
})
This is the /templates/workarea.html
<a ui-sref="workarea.shared">Shared</a>
<a ui-sref="workarea.user">Private</a>
<div ui-view="options" />
<div ui-view="workspace" />
When clicked on Shared, the views (options, workspace and comments) of workarea.shared should be loaded and when clicked on Private the views (options, workspace) of workarea.user should be loaded.
What am I missing here?
There is a working version
There are two issues. Firstly, <div> cannot be self closing, so this is a fix of the parent template
<div>
<a ui-sref="workarea.shared">Shared</a>
<a ui-sref="workarea.user">Private</a>
<!--
<div ui-view="options" />
<div ui-view="workspace" />
-->
<div ui-view="options" ></div>
<div ui-view="workspace" ></div>
</div>
Also, controller belongs to view (even to each of them if more defined) not to state:
...
.state("workarea.shared", {
url: "/workarea",
// NOT here - controller belongs to view
//controller: "workareaSharedCtrl",
requireLogin: true,
views: {
"options": {
templateUrl: "views/options.html",
controller: "workareaSharedCtrl", // here should be definition
},
...
Check it here
Related
I am using ui-rooter with Angularjs.
I have this button :
<button type="button"
class="btn btn-primary"
ui-sref="tool-plain({id:vm.tool.id})" target="_blank">
<i class="fa fa-user"></i> Tool
</button>
and this state file :
.state('tool-plain', {
parent: 'entity',
url: '/tool/{id}',
data: {
authorities: ['ROLE_USER'],
pageTitle: 'Tool'
},
views: {
'content#': {
templateUrl: 'app/entities/tool/tool-plain.html',
controller: 'ToolDialogController',
controllerAs: 'vm'
}
},
resolve: {
entity: ['$stateParams', 'Tool', function($stateParams, Tool) {
return Tool.get({id : $stateParams.id});
}]
}
})
When I click on the button nothing happens.
How should I do to open the link in a new tab?
Thanks
Why this routes not working? How to force this code work? How to implement layouts work in angular-ui-router? Please help resolve this problem.
$stateProvider
.state( 'layout', {
abstract: true,
url: '',
views: {
'layout': { templateUrl: 'template/layout.html' },
'header': {
templateUrl: 'template/header.html',
controller: 'HeaderController'
},
'sidebar': { templateUrl: 'template/sidebar.template.html' }
}
} )
.state( 'layout.home', {
url: '/',
views: {
'main#layout.home': { templateUrl: 'template/main.html' }
}
}
);
layout.html
<main class="layout">
<div ui-view="header"></div>
<div class="main">
<div class="container">
<div class="row">
<div class="col-md-9">
<div class="content">
<div ui-view="main"></div>
</div>
</div>
<div class="col-md-3">
<div ui-view="sidebar"></div>
</div>
</div>
</div>
</div>
</main>
index.html
<div ui-view="layout"></div>
This should work
.state( 'layout', {
abstract: true,
url: '',
views: {
'layout': { templateUrl: 'template/layout.html' },
'header': {
templateUrl: 'template/header.html',
controller: 'HeaderController'
},
//'sidebar': { templateUrl: 'template/sidebar.template.html' }
'sidebar#layout': { templateUrl: 'template/sidebar.template.html' }
}
} )
.state( 'layout.home', {
url: '/',
views: {
//'main#layout.home': { templateUrl: 'template/main.html' }
'main': { templateUrl: 'template/main.html' }
}
}
The parent state 'layout' - is now targeting 'sidebar#layout' - using absolute naming, to find a template inside of the 'template/layout.html'
The child view is simply using parents target 'main' so we do not need absolute naming. And if we want, it would be just
'main#layout': { templateUrl: 'template/main.html' }
because we target parent's 'layout' target ui-view="main"
Working example could be found here (with some more details)
Nested states or views for layout with leftbar in ui-router?
Try with this:
$stateProvider
.state( 'layout', {
abstract: true,
url: '',
views: {
'layout': {
templateUrl: 'template/layout.html'
}
}
} )
.state( 'layout.home', {
url: '/',
views: {
'main': {
templateUrl: 'template/main.html'
},
'header': {
templateUrl: 'template/header.html',
controller: 'HeaderController'
},
'sidebar': {
templateUrl: 'template/sidebar.template.html'
}
}
}
);
I have the following state in my app:
state('app', {
url: '',
abstract: true,
templateUrl: 'app/shared/layouts/app.html',
controller: 'appController'
});
The app.html layout have those views:
<header id="topbar" ui-view="top"></header>
<section id="content" ui-view="content"></section>
The "top" view is basically the breadcrumb. But in some features, they are more complex and have a lot of buttons, tabs, etc.
So, in my states, I have:
.state("dashboard", {
parent: 'app',
url: '/dashboard',
views: {
'top': { templateUrl: "app/dashboard/top.html" }
'content': { templateUrl: "app/dashboard/dashboard.html" }
},
controller: 'Dashboard as vm',
data: { requireAuth: true }
});
Is there any way to have a default top template in all states, and only if I want, overwrite this template?
I already tried put the default template into the view:
<header id="topbar" ui-view="top">
<ul class="breadcrumb">[...]</ul>
</header>
Works, but give me a lag between state changes (the default top disapears after the custom top has loaded)
Option 1:
Define the layout in the index (or a parent state) and target the named views at the root state
Plunk 1
index.html:
<body ng-app="plunker">
<a ui-sref='app.child1'>Go to child1</a>
<a ui-sref='app.child2'>Go to child</a>
<h1>Hi from unnamed view in app state</h1>
<div ui-view='header'></div>
<div ui-view='content'></div>
</body>
config:
$stateProvider.state('app', {
url: "",
views: {
"header#": {
template: "<h3>Default header template</h3>"
},
"content#": {
template: "<h5>Default content template</h3>"
}
}
}).state('app.child1', {
url: '/child1',
views: {
"header#": {
template: "<small>Header for child1</small>"
},
"content#": {
template: "<a ui-sref='^'>Back to parent</a><h1>child1</h1>"
}
}
}).state('app.child2', {
url: '/child2',
views: {
"header#": {
template: "<small>Header for child2</small>"
},
"content#": {
template: "<a ui-sref='^'>Back to parent</a><h1>child1</h1>"
}
}
});
Option 2
Define the layout in the app state, as well as the default views to plug into the layout
Plunk 2
index.html:
<body ng-app="plunker">
<div ui-view></div>
</body>
config:
$stateProvider.state('app', {
url: "",
views: {
"header#app": {
template: "<h3>Default header template</h3>"
},
"content#app": {
template: "<h5>Default content template</h3>"
},
"#": {
template: "<a ui-sref='.child1'>Go to child1</a>" +
"<a ui-sref='.child2'>Go to child2</a>" +
"<h1>Hi from unnamed view in app state</h1>" +
"<div ui-view='header'></div>" +
"<div ui-view='content'></div>"
}
}
}).state('app.child1', {
url: '/child1',
views: {
"header#app": {
template: "<small>Header for child1</small>"
},
"content#app": {
template: "<a ui-sref='^'>Back to parent</a><h1>child1</h1>"
}
}
}).state('app.child2', {
url: '/child2',
views: {
"header#app": {
template: "<small>Header for child2</small>"
},
"content#app": {
template: "<a ui-sref='^'>Back to parent</a><h1>child2</h1>"
}
}
});
I have the following code. The issue is it isnt showing either view. What am i doing wrong?
.state('app.accessmanager.user.reactivate', {
url: '/reactivate',
Views: {
'': {templateUrl: 'assets/views/accessmanager/reactivate.html'},
title: 'ReActivate User',
icon: 'ti-layout-media-left-alt',
ncyBreadcrumb: {
label: 'ReActivate User'
},
'sideBar': {templateUrl: 'assets/views/partials/AMSidebar.html'}
}
here is the markup.
<div class="sidebar app-aside" id="sidebar" toggleable parent-active-class="app-slide-off" >
<div perfect-scrollbar wheel-propagation="false" suppress-scroll-x="true" class="sidebar-container">
<div ui-view="sideBar"></div>
</div>
</div>
<div class="app-content" ng-class="{loading: loading}">
<header data-ng-include=" 'assets/views/partials/top-navbar.html' " class="navbar navbar-default navbar-static-top"></header>
<div data-ng-include=" 'assets/views/partials/main-content.html' " class="main-content" ></div>
</div>
if I do the following, it will at least display the sidebar but not the main content.
.state('app.access', {
url: '/access',
views: {
'sideBar': {
templateUrl: 'assets/views/partials/AMSidebar.html'
}
},
template: '<div ui-view class="fade-in-up"></div>',
title: 'ACCESS MANAGER',
ncyBreadcrumb: {
label: 'ACCESS MANAGER'
}
})
As a lack of codepen, I can only suppose :
Try to replace :
Views: {
'': {templateUrl: 'assets/views/accessmanager/reactivate.html'},
title: 'ReActivate User',
icon: 'ti-layout-media-left-alt',
ncyBreadcrumb: {
label: 'ReActivate User'
},
'sideBar': {templateUrl: 'assets/views/partials/AMSidebar.html'}
}
with
views: {
'': {templateUrl: 'assets/views/accessmanager/reactivate.html',
title: 'ReActivate User',
icon: 'ti-layout-media-left-alt',
ncyBreadcrumb: {
label: 'ReActivate User'
} // ADDED AFTER EDIT
},
'sideBar': {templateUrl: 'assets/views/partials/AMSidebar.html'}
}
}
I have slightly modified the JSON structure of views:
i figured it out!!!
.state('app.accessmanager.user.reactivate', {
url: '/reactivate',
views: {
'sidebar#app': {templateUrl: 'assets/views/partials/AccessManagerNav.html'},
'': {templateUrl: "assets/views/accessmanager/reactivate.html",
title: 'ReActivate User',
icon: 'ti-layout-media-left-alt',
ncyBreadcrumb: {label: 'ReActivate User'}
}
}
}
Notice the # after sidebar with the app which is the state. Also if you are going to have other attributes you have to enclose them in the {} like I did in the second templateUrl.
I have a user layout file that is the template for any user pages:
<div class="user-wrapper">
<div ui-view="menu"></div>
<div ui-view="content"></div>
</div>
Depending on the state I want the menu to be different. Such as:
.state('user', {
url: '/user',
templateUrl: 'partials/user.html',
controller: 'userController',
})
.state('user.one', {
url: '/one',
controller: 'oneController',
views: {
"menu": { templateUrl: "partials/client-menu.html" },
"content": { templateUrl: "partials/one.html" }
},
});
.state('user.two', {
url: '/two',
controller: 'twoController',
views: {
"menu": { templateUrl: "partials/client-menu.html" },
"content": { templateUrl: "partials/two.html" }
},
});
.state('user.three', {
url: '/three',
controller: 'threeController',
views: {
"menu": { templateUrl: "partials/admin-menu.html" },
"content": { templateUrl: "partials/three.html" }
},
});
Now you can see "one" and "two" both use the same menu but "three" uses a different menu. This all works fine but is there a way to avoid duplicating the menu on "one" and "two".
Such as making a "user.client" state that uses the "user-menu.html" then "one" would be "user.client.one" instead and only have to specify the content.
I think the main problem is the
<div ui-view="content"></div>
is on the grandfather of the "user.client.one" so how can it specify the content?
I would say, that the trick is to move the "menu" view definition into parent state "user"
.state('user', {
url: '/user',
views: {
"" : {
templateUrl: 'partials/user.html',
controller: 'userController',
},
"menu#user": { templateUrl: "partials/client-menu.html" },
},
...
So, what happened? any child state of the "user" will already have the content of the "menu" filled, with the default templateUrl: "partials/client-menu.html"
Any other child, can override that...
.state('user.one', {
url: '/one',
controller: 'oneController',
views: {
// "menu": already set by parent
"content": { templateUrl: "partials/one.html" }
....
.state('user.two', {
url: '/two',
views: {
// "menu": set in parent
"content": { templateUrl: "partials/two.html" }
...
.state('user.three', {
url: '/three',
controller: 'threeController',
views: {
// here we override that
"menu": { templateUrl: "partials/admin-menu.html" },
"content": { templateUrl: "partials/three.html" }
...
Maybe, check this Q & A for some more ideas about multi view nesting:
multiple ui-view html files in ui-router
AngularJS ui-router view structure product site
I think a found a solution user the # for absolute views:
.state('user', {
url: '/user',
templateUrl: 'partials/user.html',
controller: 'userController',
})
.state('user.client', {
url: '/client',
views: {
"menu": { templateUrl: "partials/client-menu.html" }
},
})
.state('user.admin', {
url: '/admin',
views: {
"menu": { templateUrl: "partials/admin-menu.html" }
},
})
.state('user.client.one', {
url: '/one',
controller: 'oneController',
views: {
"content#user": { templateUrl: "partials/one.html" }
},
});
.state('user.client.two', {
url: '/two',
controller: 'twoController',
views: {
"content#user": { templateUrl: "partials/two.html" }
},
});
.state('user.admin.three', {
url: '/three',
controller: 'threeController',
views: {
"content#user": { templateUrl: "partials/three.html" }
},
});
It feels abit cleaner but I'm not sure if its the right approach still.