Template with multiple ui-views -> Show a state in one ui-view - angularjs

My index page looks like:
{{#content "left"}}
<div ui-view="viewLeft"></div>
{{/content}}
{{#content "main"}}
<div ui-view="viewMain"></div>
{{/content}}
In "viewLeft" I'd like to have a menu with links that load/show various states in "viewMain". I cannot figure our how to do this :(
My module definition looks like:
angular
.module('__MODULE__.projektbeteiligung', ['ui.router'])
.config(function ($stateProvider) {$stateProvider
.state('projektbeteiligung', {
url: '/projektbeteiligung',
views: {
"viewLeft": {
templateUrl: 'projektbeteiligung/projektbeteiligungLeft.tpl.html'
},
"viewMain": {
templateUrl: 'projektbeteiligung/projektbeteiligung.tpl.html',
controller: 'ProjektbeteiligungController'
}
}
})
.state('antrag_informationen', {
url: '/antrag_informationen',
views: {
"viewLeft": {
templateUrl: 'projektbeteiligung/projektbeteiligungLeft.tpl.html'
},
"viewMain": {
templateUrl: 'projektbeteiligung/antrag_informationen.tpl.html',
controller: 'AntragInformationenController'
}
}
})
;
});
Somehow this works but I'd like to avoid reloading "viewLeft".

Related

Getting nested views to work with multiple modules in AngularJS and ui-router

I'm working with a large AngularJS application, which has 1 large module, which I'm trying to break down into more easily managed modules.
We have several ui-views on the main page for menu, footer, content, sidebar etc.
At the moment each $stateProvider.state is populating each of these ui-views on every state change. I want to change it to only be more hierarchical and only have the root state change these. This I can do.
However, I'm having issues when I split the application into modules. I've created a Plunker to demonstrate.
(function() {
angular
.module("acme", ["ui.bootstrap", "ui.router", "acme.admin", "acme.stock"]);
angular
.module("acme")
.config(MainModuleConfig);
MainModuleConfig.$inject = ["$stateProvider", "$urlRouterProvider", "$locationProvider"];
function MainModuleConfig($stateProvider, $urlRouterProvider, $locationProvider) {
//$locationProvider.html5Mode(true);
var root = {
name: "root",
url: "/",
views: {
"menuView": {
templateUrl: "app/menu/menuTemplate.html",
},
"mainView": {
templateUrl: "app/mainTemplate.html",
controller: "MainController",
controllerAs: "vm",
}
}
};
$stateProvider
.state("root", root);
$urlRouterProvider
.otherwise("/");
}
})();
(function() {
angular
.module("acme.admin", ["ui.router"]);
angular
.module("acme.admin")
.config(AdminConfig);
AdminConfig.$inject = ["$stateProvider", "$locationProvider"];
function AdminConfig($stateProvider, $locationProvider) {
var admin = {
name: "admin",
url: "/Admin",
views: {
"menuView": {
templateUrl: "app/menu/menuTemplate.html",
},
"mainView": {
templateUrl: "app/admin/adminTemplate.html",
}
}
};
var countries = {
name: "admin.Countries",
url: "/Admin/Countries",
views: {
"adminView": {
templateUrl: "app/admin/adminCountriesTemplate.html",
controller: "AdminCountriesController",
controllerAs: "vm"
}
}
}
var people = {
name: "admin.People",
url: "/Admin/People",
views: {
"adminView": {
templateUrl: "app/admin/adminPeopleTemplate.html",
controller: "AdminPeopleController",
controllerAs: "vm"
}
}
}
$stateProvider
.state("admin", admin)
.state("admin.Countries", countries)
.state("admin.People", people);
}
})();
In the admin module and others, I don't want to have to set the "menuView" again, but I can't see how to reference the parent
I managed to fix the issue:
First I set up the root state in the main module:
var root = {
name: "root",
url:"/",
views: {
"menuView": {
templateUrl: "app/menu/menuTemplate.html",
},
"mainView": {
templateUrl: "app/mainTemplate.html",
controller: "MainController",
controllerAs: "vm",
}
}
};
Then in the child modules, I changed the main node to be a child of root and also suffixed the ui-view name with an #:
var admin = {
name: "root.admin",
url: "/Admin",
views: {
"mainView#": {
templateUrl: "app/admin/adminTemplate.html",
}
}
};
The plunker has been updated with the working example.

Set a defaults for views in Ionic AngularJS

I'm learning Ionic framefork to develop an app.
I defined an abstract state like this:
.state('app', {
url: '',
abstract: true,
templateUrl: "templates/default.html"
})
My default.html looks like this:
<ion-side-menus>
<ion-side-menu-content>
<div ui-view="headerview"></div>
<div ui-view="contentview"></div>
</ion-side-menu-content>
<div ui-view="menuview"></div>
And then I declared all my actual states
.state('app.contacts', {
url: '/contacts',
views: {
'headerview': {
templateUrl: "templates/common/header.html" ,
controller: 'headerControllers'
},
'menuview': {
templateUrl: "templates/common/menu.html"
},
'contentview': {
templateUrl: 'templates/contacts.html',
controller: 'contactControllers'
}
}
})
.state('app.partners', {
url: '/partners',
views: {
'headerview': {
templateUrl: "templates/common/header.html" ,
controller: 'headerControllers'
},
'menuview': {
templateUrl: "templates/common/menu.html"
},
'contentview': {
templateUrl: 'templates/partners.html',
controller: 'partnerControllers'
}
}
})
This works like a charm, but I noted that header and menu views will be the same in almost all of my states! That's not very DRY. There is a way to define a default that I can overwrite when needed?
Thank you,
one way to do this is to create store your path in a variable and use it for all your state.
in the begining of your function make :
var defaultHeader = 'templates/common/header.html';
var defaultHeaderController = 'headerControllers';
var defaultMenu = 'templates/common/menu.html';
then during the init of your state you will be able to do :
.state('app.contacts', {
url: '/contacts',
views: {
'headerview': {
templateUrl: defaultHeader ,
controller: defaultHeaderController
},
'menuview': {
templateUrl: defaultMenu
},
'contentview': {
templateUrl: 'templates/contacts.html',
controller: 'contactControllers'
}
}
})
.state('app.partners', {
url: '/partners',
views: {
'headerview': {
templateUrl: defaultHeader ,
controller: defaultHeaderController
},
'menuview': {
templateUrl: defaultMenu
},
'contentview': {
templateUrl: 'templates/partners.html',
controller: 'partnerControllers'
}
}
})
Like that if you want to overwrite the default view you can.
And to update it you have only one place to modify the code.

controller undefined in named views

Following works perfect.
In my application file app.js, i have states like
.state('nna.home',
{
url: '/home',
views: {
templateUrl: 'views/home.html'
}
})
//home.html is like
<script src="../controllers/home.js"></script>
<div class="container cf" ng-controller="home">
// my home.js is included correctly in all cases have code like
alert(2); // works
app.controller('home', function ($scope) {
alert(2); // works
});
But as soon as I try to use named views like following. It stops routing
.state('nna.home', {
url: '/home',
views: {
'v1' : {
templateUrl: 'home.html',
controller: 'home',
resolve: {
deps: function ($ocLazyLoad) {
return $ocLazyLoad.load('homecontroller.js');
}
}
},
}
// my home.js is included correctly in all cases have code like
alert(2); // works
app.controller('home', function ($scope) {
alert(2); // Does not work
});
Plunker
I can use them fine as long as i load all controller files in index but i want to load controllers only with views not all the way in index
Probably the issue is with my understanding about named views, but i am stuck to know the reason that why the home is undefined even when i can show with alert that file had been successfully added
Try this:
.state('nna.home',
{
url: '/home',
views: {
'v1': {
templateUrl: 'views/home.html',
controller: 'home'
}
}
})
There is a working plunker
These could be the states:
.state('nna', {
template: '<div ui-view="v1"></div>',
})
.state('nna.home', {
url: '/home',
views: {
'v1' : {
templateUrl: 'views/home.html',
controller: 'home',
},
}
});
And these links are working now:
<a href="#/home">
<a ui-sref="nna.home">
Check it in action here

how to reference a controller inside a sub-module in angularjs

I'm using modules /sub modules on the angular app, my controller doesn't load on a specific route but the view does, according to a comment on this question I should reference the child module inside the main module and that should do the trick.
this is my code for bootstrapping the app:
angular.module('mainApp', ['ui.bootstrap', 'ui.utils', 'ui.router', 'ngResource', 'ngAnimate', 'ngCookies', 'facebook', 'subModule1', 'subModule2', 'subModule3']);
angular.module('mainApp').config(function ($stateProvider, $urlRouterProvider, $locationProvider, FacebookProvider) {
$stateProvider.state("root",
{
url: '',
abstract: true,
views: {
'footer#': {
templateUrl: "/partial/footer/footer.html",
},
'header#': {
templateUrl: "/partial/header/header.html",
}
}
}).state('root.home', {
url: '/index',
views: {
'container#': {
templateUrl: '/partial/index/index.html',
controller: 'IndexCtrl'
}
},
}
).state('root.login', {
url: "/login",
views: {
'container#': {
templateUrl: '/partial/login/login.html',
controller: 'LoginCtrl'
}
},
});
FacebookProvider.init('xxxxxx');
$urlRouterProvider.otherwise('/index');
$locationProvider.hashPrefix('!');
});
I have the sub-module configuration in a separate folder named /subModule1/submodule1.js
angular.module('subModule1').config(function($stateProvider) {
$stateProvider.state("submodule1",
{
url: '',
abstract: true,
views: {
'footer#': {
templateUrl: "/partial/footer/footer.html",
},
'header#': {
templateUrl: "/partial/header/header.html",
}
}
}).state('submodule1.dashboard',
{
url: '/dashboard',
views: {
'container#': {
templateUrl: '/subModule1/partial/dashboard/dashboard.html',
controller: 'DashboardCtrl',
resolve: {
dashboardinfo: function($resource) {
var resourceGet = $resource('/submodule1/dashboard');
return resourceGet.get().$promise;
}
}
},
'sideBar#': {
templateUrl: '/submodule1/partial/sidebar/sidebar.html'
},
'navBar#': {
templateUrl: '/submodule1/partial/navbar/navbar.html'
}
}
});
});
the controller is defined as:
angular.module('subModule1').controller('DashboardCtrl', function ($scope, $interval, $resource, notification, dashboardinfo) { ... }
the index located on the root of the page which is the page layout have the
<html ng-app="mainApp">
and the controller have the ng-controller definiton as follows:
<div ng-controller="DashboardCtrl">
Everything is fine just the controller isn't running, it doesn't get executed by the view.
The ui-router and ng-controller="DashboardCtrl" are intended to work together. In the ui-router world we are assigning Controllers to views directly in the state definition.
So this (exactly as you have already have it, no change) is enough:
.state('submodule1.dashboard',
{
url: '/dashboard',
views: {
'container#': {
templateUrl: '/subModule1/partial/dashboard/dashboard.html',
controller: 'DashboardCtrl',
to say, that the view rendered inside of the ui-view="container" on the root (index.html) should be provided with DashboardCtrl.
There is an example using the above state definition (1:1 as possible).
This is the index.html content:
<div ui-view="header"></div>
<div ui-view="navBar"></div>
<div ui-view="container"></div>
<div ui-view="sideBar"></div>
<div ui-view="footer"></div>
And this links will correctly trigger the above states:
// root
<li><a ui-sref="root.home">root.home</a></li>
<li><a ui-sref="root.login">root.login</a></li>
// dashboard
<li><a ui-sref="submodule1.dashboard">submodule1.dashboard</a></li>
All the other details check here

Angular UI-Router multiple views

I am using angular UI-Router. I have the following in my route config
.config(function config($stateProvider) {
$stateProvider.state('newsFeedView', {
url: '/newsFeed',
controller: 'newsFeedController',
templateUrl: '../src/app/bulletinBoard/views/newsFeed.part.html',
data: {
pageTitle: 'News Feed'
}
})
.state('tradeFeedView', {
url: '/tradeFeed',
controller: 'tradeFeedController',
templateUrl: '../src/app/bulletinBoard/views/tradeFeed.part.html',
data: {
pageTitle: 'Trade Feed'
}
})
.state('bulletinBoard', {
url: '/bulletinBoard',
views: {
'tradeFeed': {
url: "",
controller: 'tradeFeedController',
templateUrl: '../src/app/bulletinBoard/views/tradeFeed.part.html'
},
'newsFeed': {
url: "",
controller: 'newsFeedController',
templateUrl: '../src/app/bulletinBoard/views/newsFeed.part.html'
}
},
templateUrl: '../src/app/bulletinBoard/views/bulletinBoard.part.html'
});
})
In my index page I just invoke the view using:
<div class="container" ui-view></div>
In My bulletinBoard.html i want to have a nested view:
<div ui-view="tradeFeed"></div>
<div ui-view="newsFeed"></div>
For the /newsFeed page and the /tradeFeed pages this works perfectly but for the bulletin board i can't see anything on the page. Where am i going wrong?
I find the example on the official GitHub wiki to be very unintuitive. Here is a better one:
https://scotch.io/tutorials/angular-routing-using-ui-router
For instance:
...
.state('bulletinBoard', {
url: '/bulletinBoard',
views: {
// the main template will be placed here (relatively named)
'': { templateUrl: '../src/app/bulletinBoard/views/bulletinBoard.part.html' },
// the child views will be defined here (absolutely named)
'tradeFeed#bulletinBoard': { template: ..... },
// another child view
'newsFeed#bulletinBoard': {
templateUrl: ......
}
}
});
The syntax of each view attribute being viewName#stateName.
The .state() method's templateUrl is ignored when using the views object. See the ui-router wiki for more info:
https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views#user-content-views-override-states-template-properties

Resources