how to reference a controller inside a sub-module in angularjs - 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

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.

Nested templates using ui-view

I'm trying to display a nested template using ui-view.
AngularJS routing config
angular.module('myApp')
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('home', {
url: '',
abstract: true
})
.state('home.default', {
parent: 'home',
url: '/home',
data: {
pageTitle: 'Homepage'
},
views: {
'content#': {
templateUrl: 'app/default/default.html',
controller: 'defaultController',
controllerAs: 'defaultController'
}
}
})
.state('default.subview', {
parent: 'default',
url: '/default/subview',
data: {
pageTitle: 'Homepage - subview'
},
views: {
'content#': {
templateUrl: 'app/subview/subview.html',
controller: 'subviewController',
controllerAs: 'subviewController'
}
}
})
;
}]);
Home: /#/home
<!-- this URI should be #/home -->
<h2>Homepage</h2>
<select>
<option>Subview</option>
</select>
<hr>
<!-- nested subview -->
<div ui-view=""></div>
Subview: /#/home/subview
<h2>Subview</h2>
So basically, I want the parent view (home) and subview's content to be included when I visit (/#/home/subview). However, only the subview content is being displayed.
Any tips on how to correctly utilize ui-view and nested subviews in AngularJS?
Your subview has to be a child of home and you set the subview with 'content#' to an defined ui-view wich replaces your view from home.
And I edited some copy paste issue since it looks like your home route was called default before
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('home', {
url: '/home',
abstract: true,
template: '<ui-view/>'
})
.state('home.default', {
url: '/home/default',
data: {
pageTitle: 'Homepage'
},
views: {
'': {
templateUrl: 'home.html',
controller: 'defaultController',
controllerAs: 'defaultController'
}
}
})
.state('home.subview', {
parent: 'home',
url: '/subview',
data: {
pageTitle: 'Homepage - subview'
},
views: {
'': {
templateUrl: 'subview.html',
controller: 'subviewController',
controllerAs: 'subviewController'
}
}
});
}]);
Edit:
I created a Plunker with an working configuration, there was some more issues with that abstract home state (I never get it to work as expected) but if you click the links everything appears as expected.
Plunker
There really is no need for the views section if you have only one ui-view
angular.module('myApp')
.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('home', {
url: '',
abstract: true,
template: '<ui-view></ui-view>'
})
.state('home.default', {
// parent: 'home', // No need to set parent if you already prefixed state name
url: '', // The default subview of an abstract view should have '' for url
data: {
pageTitle: 'Homepage'
},
templateUrl: 'app/default/default.html',
controller: 'defaultController',
controllerAs: 'defaultController'
})
.state('home.default.subview', {
// parent: 'default', // No ned for parent
url: '/subview', // Only pu the part of the url here that is added to the parent'ls url
data: {
pageTitle: 'Homepage - subview'
},
templateUrl: 'app/subview/subview.html',
controller: 'subviewController',
controllerAs: 'subviewController'
})
;
}]);
In addition I've also changed the ui-sref in index.html
<a ui-sref="home.default.subview">Subview Route</a>
And the ui-view in home.html
<!-- nested subview -->
<ui-view></ui-view>
Check this plunker:
https://plnkr.co/edit/vEDYvXhp5mNjVT0yLRJN?p=preview

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

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

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".

Angular UI router - not calling the views

I'm trying out Angular UI router for the first time. I'm having issues where the views are not being called accordingly. Check the plunker: http://plnkr.co/edit/cBfR6u2BPJvKN16vi6hG?p=preview
Does anything stand out on the router?
deviceApp.config(function ($stateProvider) {
$stateProvider
.state('devices', {
views: {
'environment': {
template: 'Look I am a view!',
controller: 'DataCtrl'
},
'devicedetail': {
templateUrl: 'index.html',
controller: 'DeviceCtrl'
}
}
}
)}
);
perhaps the absence of a "url" definition in your view object?
'environment': {
url: '/environment',
template: 'Look I am a view!',
controller: 'DataCtrl'
},
You can do something like that :
config.js
.config(function ($urlRouterProvider) {
$urlRouterProvider.otherwise('/');
$urlRouterProvider.when('', '/');
})
app.js
state('main', {
url: '/',
views: {
'': { templateUrl: 'app/main/main.html', controller: 'MainCtrl'},
'navbar': { templateUrl: 'components/navigation/navbar/navbar.html'},
}
index.html
<body>
<header ui-view="navbar" class="header"></header>
<section class="content">
<div ui-view></div>
</section>
</body>

Resources