How can I wrap by controller for views in angularJS - angularjs

I want to use parentController like the below code, is it possible?
$stateProvider
.state('main.base', {
abstract : true,
views : {
'left#main' : {
templateUrl: '',
controller : ''
},
'content-head#main': {
templateUrl: '',
controller: ''
},
'content-body#main': {
template : '<div>init page</div>'
}
},
params : {
},
controller: 'ParentController as parentCtrl'
})

Yeah it is, but you need a parent state. Eg;
$stateProvider
.state('main', {
template: '<ui-view/>',
controller: 'ParentController as parentCtrl'
})
.state('main.base', {
// your views
});
If you have views, you can't have a controller on the same state, but you can always add a state in your hierarchy to achieve the same result.

Related

Unable to use abstract state to provide initial shared views in Angular UI-router

I'm trying to provide some initial "partial" views through an abstract state using Angular and Angular UI router but somewhere along the way I'm making a misinterpretation which breaks my implementation...
As you can see I tried some variations with specifying a customLayout.html template to the abstract state. This also didn't work.
What does work (but isn't what I want) is specifying the shared partial templates on each state.
I've implemented that what does and what does not here:
See this: JSBin.
Look at: //REMOVE COMMENT HERE to switch between an "inherited" or "child" state.
$stateProvider
.state("layout", {
abstract: true,
url: "",
//templateUrl: "customLayout.html",
views: {
"header" : {
templateUrl: 'shared/header.html',
}
}
})
//REMOVE COMMENT HERE
//.state("layout.demo")
.state("demo", {
url: "/demo",
views: {
"" : {
templateUrl: 'demo.html',
},
"header" : {
templateUrl: 'shared/header.html'
}
}
});
Edit:
With help of this:
$stateProvider
.state("layout", {
abstract: true,
url: "",
//templateUrl: "customLayout.html",
views: {
"header" : {
templateUrl: 'shared/header.html',
},
//ADDED THIS, ESSENTIALLY PROXYING THE NAMELESS TEMPLATE
'': {
template: '<ui-view />'
}
}
})
Try this:
app.config([
'$stateProvider',
'$urlRouterProvider',
function ($stateProvider, $urlRouterProvider) {
console.log("app: states");
$urlRouterProvider
.otherwise('/demo');
$stateProvider
.state("layout", {
abstract: true,
url: "",
//templateUrl: "customLayout.html",
views: {
"" : {
templateUrl: 'demo.html'
},
"header" : {
templateUrl: 'shared/header.html'
}
}
})
//REMOVE COMMENT HERE
//.state("layout.demo")
.state("layout.demo", {
url: "/demo",
});
}
]);
Here is the working link:
http://jsbin.com/zehejovaco/1/edit?html,output

how to design a state with ui-router that replaces the content only of index.html with two files and two controllers

How to design a state with UI-Router that replaces the CONTENT ONLY of index.html with two files and two controllers.
i have views/dishDetail.html & views/comment.html and
I`m trying this:
.state('app.dishDetail',{
url: 'menu/:id',
views: {
'content#' : {
'disComment': {
templateUrl : 'views/dishDetail.html',
controller : 'DishDetailController'
},
'myComment': {
templateUrl : 'views/comment.html',
controller : 'DishCommentController'
}
}
}
});
please help
This should be the way
.state('app.dishDetail', {
url: 'menu/:id',
views: {
'content#': {
template: '<div ui-view="disComment" /></div>' +
'<div ui-view="myComment" /></div>',
},
'disComment#app.dishDetail': {
templateUrl: 'views/dishDetail.html',
controller: 'DishDetailController'
},
'myComment#app.dishDetail': {
templateUrl: 'views/comment.html',
controller: 'DishCommentController'
}
}
There is a working plunker

Change states without reloading common view, angular ui-router.

Summery - I have two states. Both of them have two views in them col1 and col2. In both states col1 has same templateUrl i.e. FirstTemplate.html.
Question - How can I change from state one to state two without reloading FirstTemplate.html.
I have done this by making state two a child of state one and it is working fine that way, but I find it to be an incomplete solution since parent-child structure is not suitable for me in some scenarios.
$stateProvider
.state('one',{
views: {
'col1': {
templateUrl: 'FirstTemplate.html'
},
'col2': {
templateUrl: 'SecondTemplate.html'
}
},
.state('two',{
views: {
'col1': {
templateUrl: 'FirstTemplate.html'
},
'col2': {
templateUrl: 'ChangedTemplate.html'
}
}
})
I think the best solution might be to use a parent abstract state, like on this way:
.state( 'parent', {
abstract : true,
templateUrl : 'FirstTemplate.html'
})
.state( 'parent.one', {
templateUrl : 'SecondTemplate.html',
})
.state( 'parent.two', {
templateUrl : 'ChangedTemplate.html',
})
And, in order to yield both children views, you have to add this on FirstTemplate:
<div ui-view></div>
I think this will solve your problem.
PS: you need to specify also the url on the states
You'll need a hierarchical state structure, but both views have the same parent.
$stateProvider
.state('root', {
abstract: true,
url: '/root',
views: {
'col1': {
templateUrl: 'FirstTemplate.html',
controller: function($scope) {
$scope.lastUpdate = new Date();
}
}
}
}).state('root.one', {
url: '/one',
views: {
'col2': {
templateUrl: 'SecondTemplate.html',
controller: function($scope) {
$scope.lastUpdate = new Date();
}
}
}
})
.state('root.two', {
url: '/two',
views: {
'col2': {
templateUrl: 'ChangedTemplate.html',
controller: function($scope) {
$scope.lastUpdate = new Date();
}
}
}
});
Plunker

Angular UI-Router, Parent ui-view renders but child view with templates do not

If I have index.html with:
<body>
<ui-view="home"></home>
</body>
Then inside that home view i render frame.html with the following inside:
<div ui-view="home_content"></div>
In my app.js I've been trying to get the most inner the ui-view inside frame.html to render another html template. I'm able to render the content in the home view just fine but nothing renders inside home_content.
My app.js ui-router code
$stateProvider
.state('user', {
abstract: true,
template: '<ui-view/>',
data: {
access: AccessLevels.user
}
})
.state('user.home', {
url: '/home',
views: {
'home#': {
templateUrl: 'app/partials/home/frame.html',
controller: 'homeCtrl'
},
'home_content#home': {
templateUrl: 'app/partials/home/dashboard/index.html',
controller: 'dashboardCtrl'
}
}
});
Seems like I may be coming at this all wrong, not sure if the above is the right way to go about it.
There is a working plunker
I would expect, that you want to target unnamed view of your parent in the child, so the view should be defined like this:
$stateProvider
// here we define parent
.state('user', {
abstract: true,
// parent has UNNAMED view
template: '<ui-view/>', // this will be injected into index.html
... // ui-view=""
})
// child will partilly target parent
// and also itself
.state('user.home', {
url: '/home',
views: {
// here we target parent UNNAMED view
'': {
...
},
// here we target current state
// so we should use state name
'home_content#user.home': {
...
}
}
});
What would also work is instead of '' : { } we can use '#home' : {} (see the doc below).
In case (as mentioned below in the comment) we have index.html with target named home:
<div ui-view="home"></div>
We can use this plunker, which redefines the parent abstract state like this:
$stateProvider
.state('user', {
abstract: true,
data: {
...
},
views : {
'home' : {
template: '<div ui-view=""></div>',
}
}
})
Check the doc
View Names - Relative vs. Absolute Names
Behind the scenes, every view gets assigned an absolute name that follows a scheme of viewname#statename, where viewname is the name used in the view directive and state name is the state's absolute name, e.g. contact.item. You can also choose to write your view names in the absolute syntax.
For example, the previous example could also be written as:
.state('report',{
views: {
'filters#': { },
'tabledata#': { },
'graph#': { }
}
})
Looks like your child .state has wrong code it should be 'home#home_content' instead of 'home_content#home'
.state('user.home', {
url: '/home',
views: {
'': {
templateUrl: 'app/partials/home/frame.html',
controller: 'homeCtrl'
},
'home#home_content': {
templateUrl: 'app/partials/home/dashboard/index.html',
controller: 'dashboardCtrl'
}
}
});
You are making your state configuration complex. Just change your code to look like this:
$stateProvider.state('user', {
abstract : true,
template : '<ui-view/>',
data : {
access : AccessLevels.user
}
})
.state('user.home', {
url : '/home',
views : {
'home' : {
templateUrl : 'app/partials/home/frame.html',
controller : 'homeCtrl'
},
'home_content' : {
templateUrl : 'app/partials/home/dashboard/index.html',
controller : 'dashboardCtrl'
}
}
});
You are actually not using # properly and which is optional. This should work unless you have your correct view path.

Can a Controller be Eagerly Loaded in AngularJS?

I am using UI router to define several states and their child views. I set their controllers accordingly as well.
I'd like one or more of those controllers to be active before the view is loaded, because of data fetching and some other operations.
Is this possible? Is this a good/bad idea?
.state(stateNames.MY_STATE, {
url: '/products/:view',
views: {
'items-of-count#my.state': {
templateUrl: 'path/to/template.html',
controller: 'NotYetLoadedController'
},
'selected-items-count#my.state': {
templateUrl: 'path/to/this/template.html',
controller: 'NotYetLoadedController'
}
},
params: {
view: {
squash: true
}
}
})

Resources