I am novice to angularjs. i want to know that is there any way to render html template based on route inside div of other page. let me explain with an example.
/Employee/Add is route which show a add.html template to add new employee.
can i render this add.html or /Employee/Add route in other 'abc.html' page ??. i know we can use ng-include directive to render any html template. but i am looking based on route.
is that possible ??
You can do this using UI-router. Your basically creating a child state. Common use case is to create Tabs within a page. It would look something like this:
.state('league.games', {
url: '/games',
views: {
'tabContent': {
templateUrl: 'app/games/games.html',
controller: 'GamesCtrl',
controllerAs: 'vm',
resolve: {
initialData: ['$stateParams', 'gamesInitialDataService',
function($stateParams, gamesInitialDataService) {
return gamesInitialDataService.getData($stateParams.leagueId);
}]
}
}
}
})
Related
In my Angular app, I have the following sample route definition which uses nested views:
.state('mapping.project', {
authenticate: true,
url: '/:projectId/:projectName',
controller: 'ProjectCtrl as proj',
views: {
'': {
templateUrl: 'app/components/mapping/partials/project.html',
controller: 'ProjectCtrl as proj'
},
'details#project': {
templateUrl: 'app/components/mapping/partials/details.html'
},
'activityTypes#project': {
templateUrl: 'app/components/mapping/partials/activity-types.html'
},
'boundaryPartners#project': {
templateUrl: 'app/components/mapping/partials/boundary-partners.html'
},
'progressMarkers#project': {
templateUrl: 'app/components/mapping/partials/progress-markers.html'
},
'users#project': {
templateUrl: 'app/components/mapping/partials/users/users.html',
controller: 'projectUserCtrl as vm'
}
}
})
Each of these views is loaded within a tab, using Angular Material md-tabs: https://material.angularjs.org/latest/api/directive/mdTabs
The problem is, when I access the route mapping.project, the projectUserCtrl that you can see on my users#project view gets immediately called. I assume the same would be true for each individual controller that I have attached to my nested views.
I'd want to call these nested controllers only when the tab is active and that particular template loaded (in this case: users#project).
How do I do this?
You don't need all these child views, you only need 1, a container for the visible tab. Make separate states for each of the tabs, then route the child view accordingly when your "tabs" are clicked.
I'm not sure on the material design specifics, but in essence your tabs become just links ui-sref links.
I'm new to using Angular UI Router and I seem to be having difficulty being able to update a parent view from it's child view.
I have the following HTML structure (restructured for easier reading, obviously views are in separate html files).
<div ui-view="main">
{ main content }
<div ui-view="tab">
{ tabbed content }
</div>
</div>
Inside tab I have the following sref:
<span ui-sref="silverstone.platforms.view({_id: platform._id})">{{platform.name}}</span>
And here are my states: (I'm using webpack, hence require)
$stateProvider
.state('silverstone', {
url: '/silverstone',
views: {
'main': {
controller: 'SilverstoneCtrl',
template: require('./templates/index.html')
}
}
});
$stateProvider
.state('silverstone.platforms', {
url: '/platforms',
views: {
'tab': {
controller: 'SilverstoneCtrl',
template: require('./templates/platforms.html')
}
}
});
$stateProvider
.state('silverstone.platforms.view', {
url: '/:_id',
views: {
'main': {
controller: 'SilverstoneCtrl',
template: require('./templates/platform-view.html')
}
}
});
When the above sref is clicked, the "main" view needs to be updated. The URL is updating but the views aren't...?
I was missing # in my silverstone.platforms.view state to explicitly address the parent view.
$stateProvider
.state('silverstone.platforms.view', {
url: '/:_id',
views: {
'main#': {
controller: 'SilverstoneCtrl',
template: require('./templates/platform-view.html')
}
}
});
Use reload: true parameter in yout ui-sref links like this.
ui-sref="silverstone.platforms.view({_id: platform._id})" ui-sref-opts="{reload: true}"
Edit:
Maybe your problem are caused by nested states combined with flat template structure.
Other solution may be to properly nest your templates, as states.
For example we have states app and app.substate, then we have two templates for both states. Tempalte of app state contains ui-view directive. (that means every state contains new ui-view directive for injecting of substate template). States are nested by default, this would represent appropriately nested templates.
I have a question about multiple views. It's difficult to explain but I'll try:
Navigating to state 'About' and setting template url for ui-view 'columnOne' and ui-view 'columnTwo' was done succesfully
.state('about', {
url: '/about',
views: {
// the main template will be placed here (relatively named)
'': { templateUrl: 'partial-about.html' },
// the child views will be defined here (absolutely named)
'columnOne#about': { template: 'Look I am a column!' },
// for column two, we'll define a separate controller
'columnTwo#about': {
templateUrl: 'table-data.html',
controller: 'scotchController'
}
}
});
Now I would like to set the templateUrl of view 'columTwo' from view 'columnOne'.
How is this done? Is it possible?
The example your taking from there website is parallel view example not nested view nested view can be made by making a page and than making other states with . like registration is a page and multistep form than the page containing registration uiview will we state registration and the parts with be like registration.contact,registration.acadamics, registration.extraactivities. And really man there documentation is quiet confusing
I would like to make a bootstrap tabset with each tab having it's own controller. Can anyone point me in which direction I should go.
Currently I have made several difference controllers, which I would like to be used in a tabset instead of having them displayed as a different route.
I know I could fake it by having the tabset in the difference controller templates displaying the given controllers tab as active, but I would like to be able to have a main TabController with several child controllers (for each tab)
If you are using angular ui router you can use nested states to do this.
Create an abstract state with a view that contains the tabs and a nested ui-view
Create a child state for each of your tabs, each inheriting from the abstract state
Each child state can set the content of the nested ui-view, and define a controller
$stateProvider.state( 'tabs', {
abstract: true,
url: 'tabs',
views: {
"tabs": {
controller: 'TabsCtrl',
templateUrl: 'tabs.html'
}
}
})
.state('tabs.tab1', {
url: '', //make this the default tab
views: {
"tabContent": {
controller: 'Tab1Ctrl',
templateUrl: 'tab1.html'
}
}
})
.state('tabs.tab2', {
url: '/tab2',
views: {
"tabContent": {
controller: 'Tab2Ctrl',
templateUrl: 'tab2.html'
}
}
});
Why don't you put a directive on each tab that has it's own controller? If you are using 1.x. Separate your code out by directive not tabs
Is it possible to setup a route in ui-router that only has a controller? The purpose being that at a certain URL, the only thing I'd like to do is take action programatically, and not display anything in terms of a view. I've read through the docs, but I'm not sure if they offer a way to do this.
Yes, I have read this: https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-open-a-dialogmodal-at-a-certain-state, but that is not quite what I am looking for.
For example, let's just say I have a basic body with view:
<body ui-view></body>
And some basic config:
// Routes
$stateProvider
.state('myaction', {
url: "/go/myaction",
onEnter: function() {
console.log('doing something');
}
});
When /go/myaction is visited, the view is blank. Is it possible to do this?
I was able to solve this problem by redirecting the headless state I was taking programmatic action in, to a state WITH a view at the end of the headless state:
$stateProvider
.state('myaction', {
url: "/go/myaction",
onEnter: function() {
console.log('doing something');
}
controller: function($state) {
$state.go('home');
}
});
You can't have a controller without a view but you can use onEnter instead of a controller. If you don't want to change the current view when accessing this state you can define it as a child state:
$stateProvider
// the parent state with a template
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'HomeCtrl'
})
// child of the 'home' state with no view
.state('home.action', {
url: '/action',
onEnter: function() {
alert('Hi');
},
});
Now in home.html you can do something like this:
<a href ui-sref=".action">Greet me!</a>
From the docs:
Warning: The controller will not be instantiated if template is not defined.
Why don't you use an empty string as a template to overcome this?
Yes, you can do that. Use absolute view names to re-use the <ui-view> of another state.
Take a look at this example:
Users go to my app, but depending on them being authenticated or not, I want to send them to a public or private page. I use the index state purely to see if they're logged in or not, and then redirect them to index.private or index.public.
The child states make use of absolute view names to use the <ui-view> element that corresponds to the index state. This way, I don't need to make a second nested <ui-view>.
$stateProvider.state('index', {
url: "/",
controller: 'IndexCtrl'
}).state('index.private', {
views: {
"#": {
templateUrl: 'private.html',
controller: 'PrivateCtrl'
}
}
}).state('index.public', {
views: {
"#": {
templateUrl: 'public.html',
controller: 'PublicCtrl'
}
}
});
A small note on this example: I'm using the # shortcut here. Normally you would use viewname#statename.
My solution for this was just to include a template (html file) that is blank.