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
Related
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".
I have code like this
<a ui-sref="nested.something">something</a>
<div ui-view="nested.something"></div>
how to load ui-view without click ui-sref ?
EXTEND - related to this plunker provided by OP in the comments above
The state definition is:
.state('store', {
views: {
'store': {
templateUrl: 'store.html'
}
}
})
.state('store.detail', {
views: {
'store_detail': {
templateUrl: 'store_detail.html'
}
}
})
Then in this updated plunker we can see that this would do the job
//$urlRouterProvider.otherwise('/store');
$urlRouterProvider.otherwise(function($injector, $location){
var state = $injector.get('$state');
state.go('store.detail');
return $location.path();
});
Reason? states do not have defined url. Which is a bit weird. So, I would honestly rather suggested to do it like this (the link to such plunker):
$urlRouterProvider.otherwise('/store/detail');
//$urlRouterProvider.otherwise(function($injector, $location){
// var state = $injector.get('$state');
// state.go('store.detail');
// return $location.path();
//});
$stateProvider
.state('store', {
url: '/store',
views: {
'store': {
templateUrl: 'store.html'
}
}
})
.state('store.detail', {
url: '/detail',
views: {
'store_detail': {
templateUrl: 'store_detail.html'
}
}
})
There is a working plunker
ORIGINAL
We can use the .otherwise(rule) of $urlRouterProvider, documented here
$urlRouterProvider.otherwise('/parent/child');
As the doc says:
otherwise(rule)
Defines a path that is used when an invalid route is requested.
So, this could be used for some default - start up "redirection"
The .otherwise() could be even a function, like shown here:
How not to change url when show 404 error page with ui-router
which takes '$injector', '$location' and can do even much more magic (on invalid or startup path)
$urlRouterProvider.otherwise(function($injector, $location){
var state = $injector.get('$state');
state.go('404');
return $location.path();
});
ALSO, if we want to fill in some more details into some nested viesw, we can do it by defining multi-named views:
.state('parent.child', {
url: "/child",
views: {
'' : {
templateUrl: 'tpl.child.html',
controller: 'ChildCtrl',
},
'nested.something#parent.child' : {
templateUrl: 'tpl.something.html',
},
}
})
So, if the tpl.child.html will have this anchor/target:
<i>place for nested something:</i>
<div ui-view="nested.something"></div>
it will be filled with the tpl.something.html content
Check it in action here
I want to be able to use one single route for two different views.
For example right now, I have two routes.
One is /home which is the main page when someone can register/login
And the other one /feed, this is when the user is logged in.
What I want to do is having a single route like twitter for example :
twitter.com/
first they ask you to login
twitter.com/
Than we can see our feed wall. And it's still the same "/". Hope I'm clear :)
This is my code so far:
$stateProvider
.state('index', {
url: '/',
controller: function($state, $auth) {
$auth.validateUser()
.then(function(resp) {
$state.go('feed');
})
.catch(function(resp) {
$state.go('home');
});
}
})
.state('home', {
url: '/home',
templateUrl: 'home.html'
})
.state('feed', {
url: '/feed',
templateUrl: 'feed.html'
})
As far as I remember ui-router doesn't support such feature so you have to do it yourself.
What you can do is to define only a single state as you did in 'index' and instead of performing the $auth logic in the controller do it in a the "resolve" section.
then you can use "ng-if" and "ng-include" to define which .html file and controller you'd like to load, something like this:
app.js
$stateProvider
.state('index', {
url: '/',
resolve: {
isAuthenticated: function() {
return $auth.validateUser().then(function(res) {
return true;
}, function(error) {
return false;
});
}
},
controller: function($scope, isAuthenticated) {
$scope.isAuthenticated = isAuthenticated;
},
templateUrl: 'index.html'
})
index.html
<div ng-if="isAuthenticated">
<div ng-include="'feed.html'"></div>
</div>
<div ng-if="!isAuthenticated">
<div ng-include="'login.html'"></div>
</div>
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
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