I have AngularJS(1.4.9) project that is build with usage of ui-router and have few states like this:
.state('overview', {
url: '/overview',
parent: 'dashboard',
templateUrl: 'views/dashboard/overview.html'
})
.state('settings', {
url: '/settings',
parent: 'dashboard',
templateUrl: 'settings/views/index.html',
controller: "SettingsCtrl"
})
Now I want to add want to integrate ng-admin(0.9.1) to it. I have tested it as standalone app with standalone html as described in docs and it works. But I couldn't find a way to add it to current project.
You will have to change your app parent state with ng-admin like below
// from
myApp.config(function ($stateProvider) {
$stateProvider.state('send-post', {
parent: 'main',
url: '/sendPost/:id',
params: { id: null },
controller: sendPostController,
controllerAs: 'controller',
template: sendPostControllerTemplate
});
});
// to
myApp.config(function ($stateProvider) {
$stateProvider.state('send-post', {
parent: 'ng-admin', // <= this has changed
url: '/sendPost/:id',
params: { id: null },
controller: sendPostController,
controllerAs: 'controller',
template: sendPostControllerTemplate
});
});
For reference please check updated document ng-admin
My 'just works' solution is to add to main project states external link of ng-admin:
.state('database', {
onEnter: function($window) {
$window.open('/ng-admin/ng-admin.html', '_self');
}
})
Related
How to handle the situation when you enter an URL for example http://localhost/#!/somepage/ but the problem is that AngularJS doesn't handle it and doesn't load the page, otherwise if you go to somepage through the index file it works correctly.
I use ui-router and my routing script looks like:
angular.module('WEBAPP', ['ui.router', 'bw.paging'])
.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.when('', '/');
var states = [
{
name: 'home',
url: '/',
templateUrl: 'application/partials/home_header.html'
},
{
name: 'somepage',
url: 'somepage/',
templateUrl: 'application/partials/somepage.html',
},
{
name: '404',
url: '404/',
templateUrl: 'application/partials/404.html'
},
]
states.forEach(function (state) {
$stateProvider.state(state);
});
});
How to do the right routing, I want, when I enter url in browser http://localhost/#!/somepage/ AngularJS automatically redirect to that page.
Try it without the for each.I might be wrong but i Think when you are using for each in here only the last state gonna bind the $stateprovider instead of binding all the states. try it like this.
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'application/partials/home_header.html'
})
.state('somepage', {
url: 'somepage/',
templateUrl: 'application/partials/somepage.html',
})
.state('404', {
url: '404/',
templateUrl: 'application/partials/404.html'
})
edited
change the url this url: 'somepage/'
to this url: '/somepage'
and when you are calling remove the ! mark in the url.just http://localhost/#/somepage is enough.
var states = [
{
name: 'home',
url: '/',
templateUrl: 'application/partials/home_header.html'
},
{
name: 'somepage',
url: '/somepage',
templateUrl: 'application/partials/somepage.html',
},
{
name: '404',
url: '/404',
templateUrl: 'application/partials/404.html'
},
]
states.forEach(function (state) {
$stateProvider.state(state);
});
Use this
angular.module('WEBAPP', ['ngRoute'])
.config(function ($routeProvider) {
$routeProvider.when('/home', {
templateUrl: 'application/partials/home_header.html'
}).when('/somepage', {
templateUrl: 'application/partials/somepage.html'
}).otherwise({
templateUrl: '/home'
});
});
I'm working on a web-app with ionic tabs.
On one of my pages i implemented the ion-tree-list from GitHub (Ion-tree-list from GitHub) as treeview.
In services.js i got the source for my tree:
.factory('VerificationTree', function () {
var verificationTree = [
{
id: 'operator',
name: 'Operator'
},
{
id: 'type_of_test',
name: 'Type of test',
},
{
id: 'system',
name: 'System'
},
{
id: 'component',
name: 'Component'
},
{
id: 'component_group',
name: 'Component group',
tree: [
{
id: 'component2',
name: 'Component'
}
]
}
];
return {
all: function () {
return verificationTree;
}
};
})
When i click on one the tree items - p.e. "type_of_test" - i want to open another page.
In controller.js i have defined a controller for the page with the tree.
Inside the Controller is a function, which opens the page by window.open.
.controller('VerificationCtrl', function ($scope, VerificationTree) {
$scope.verificationTree = VerificationTree.all();
$scope.$on('$ionTreeList:ItemClicked', function (event, item) {
if (item.id == 'type_of_test') {
window.open('templates/type-of-test.html');
};
//if (item.id == 'component2') {
// alert('The ion-tree-list item component2 was clicked');
//};
})
})
The page opens in a new tab but the layout is not okay anymore.
Is there a possibility to combine the tree with a navigation view like the following?
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('tab', {
url: '/tab',
abstract: true,
templateUrl: 'templates/tabs.html'
});
Or another example:
var app = angular.module('myApp', ['ionic']);
app.config(function($stateProvider) {
$stateProvider
.state('index', {
url: '/',
templateUrl: 'home.html'
})
.state('music', {
url: '/music',
templateUrl: 'music.html'
});
});
Not sure if I get you right, but what about doing a simple state change, when an item is clicked?
$stateProvider.state("tabs", {
url: "/tabs",
templateUrl: "templates/TabView.html",
abstract: true,
controller: "TabCtrl as tab"
}).state("tabs.home", {
url: "/overview",
templateUrl: "templates/HomeView.html",
controller: "HomeCtrl"
}).state("tabs.detail", {
url: "/detail/:id",
templateUrl: "templates/DetailView.html",
controller: "DetailCtrl"
})
On HomeView, add your TreeList and define the click function as follows:
.controller('HomeCtrl', function ($scope, $state, VerificationTree) {
$scope.verificationTree = VerificationTree.all();
$scope.$on('$ionTreeList:ItemClicked', function (event, item) {
if (item.id == 'type_of_test') {
$state.go('tabs.detail')
};
})
})
If you want to pass in the item as a param, you can define this in the stateProvider configuration as well. Check the UI-Router docs for additional information. https://github.com/angular-ui/ui-router/wiki/URL-Routing
Also if you don't want to transition to another tab when clicking an item, but stay in the tab and just change the state, you might try nested states. You could define your states like this:
$stateProvider.state("tabs", {
url: "/tabs",
templateUrl: "templates/TabView.html",
abstract: true,
controller: "TabCtrl as tab"
}).state("tabs.home", {
url: "/home",
abstract: true,
views: {
"home": {
template: "<ion-nav-view></ion-nav-view>"
}
}
}).state("tabs.home.overview", {
url: "/overview",
templateUrl: "templates/HomeView.html",
controller: "HomeCtrl"
}).state("tabs.home.detail", {
url: "/detail/:id",
templateUrl: "templates/DetailView.html",
controller: "DetailCtrl"
})
And then transition from Overview to Detail like this:
$state.go('tabs.home.detail')
is it possible to create a nested views in ui router with conditions?
The conditions is assigned to the user roles.
For example I have two types of users: admin and user.
If user is opening the setting page then ui router is adding only this view which is assign to his role.
Here is example of my config code
var app = angular.module('myApp', ['ui.router']);
app.config(function ($stateProvider, $urlRouterProvider){
$stateProvider
.state('home', {
url: '/home',
templateUrl: '/home.html',
controller: 'homeController'
})
.state('settings', {
url: '/settings',
data: {
roles: ['admin', 'moderator', 'user']
},
views:{
'':{
templateUrl:'/settings.html',
},
'piView#settings':{
data: {
roles: ['user']
},
templateUrl:'/personalInformation.html'
},
'permissionsView#settings':{//load this view if user is administrator
//I need some condition for this
data: {
roles: ['admin']
},
templateUrl: '/permissionsView.html'
}
},
controller: 'settingsController'
});
$urlRouterProvider.otherwise( function($injector) {
var $state = $injector.get("$state");
$state.go('/home');
});
});
The view will be injected for each user (admin or anonymous). But we can manage which view. The best vay would be to use templateProvider.
Based on this Q & A:
Confusing $locationChangeSuccess and $stateChangeStart
I used the plunker from above source and adjusted it a bit
So, let's have these two targets (inside of index.html)
<div ui-view="onlyForAdmin"></div>
<div ui-view=""></div>
And a state public, which for Admin will reveal even content of the onlyForAdmin, with settings like this:
.state('public', {
url: "/public",
data: { isPublic: true },
views: {
'#' : {
templateUrl: 'tpl.html',
data: { isPublic: true },
},
'onlyForAdmin#' : {
templateProvider: ['$templateRequest','userService',
function($templateRequest,userService)
{
if(userService.isAdmin())
{
return $templateRequest("justForAdmin.html");
}
return ""; // other than admin will see nothing
}
]
}
}
})
the content of the justForAdmin.html (e.g. <h2>just for admin</h2>) will be injected only of some authorization service will find user as admin...
Check it here
I have the following state configuration. How can I get id parameters in index state # view so that it could be accessible by both, left and detail views controllers? Now if I try to access it via $state.params.id it is undefined, but if I console.log($state) I can see the parameter in my console. I only need the parameter if available on first load of left view.
$stateProvider
.state('index', {
url: '/',
views: {
'#' : {
template: '/**/'
resolve: {
params: function ($state) {
return $state.params.id;
}
}
},
'left#index' : {
template: '/**/',
controller: 'AppController',
controllerAs: 'app'
},
'main#index' : {
template: '/**/'
}
})
.state('index.detail', {
url: '/:id',
views: {
'detail#index' : {
template: '/**/',
controller: 'DetailController',
controllerAs: 'detail',
}
}
});
I have now tried whole day and i cant figure out how i shall solve this issue.
My goal is to display a sidebar thats get filled with data based on what state it is.
Lets say i am on the home page i may like this items:
Home item 1
Home item 2
And if i am on the about page i want this items:
About me
About my dog
I would like the data to get fetched from a service that returns data to the view based on what state it is.
I have tried to use ui.router's resolve function but i can't get the correct structure in my head to make it work.
Created a plunkr that shows how i mean but without the solution, what are the best practices and preferred ways when creating a dynamic sidebar with Angular and ui.router?
myapp.config(function($stateProvider) {
$stateProvider
.state('home', {
url: "",
views: {
"content": {
template: "This is the home.content"
},
"sidebar": {
templateUrl: 'sidebar.html',
controller: 'sidebarCtrl'
}
}
})
.state('about', {
url: "/about",
views: {
"content": {
template: "This is the about.content"
},
"sidebar": {
templateUrl: 'sidebar.html',
controller: 'sidebarCtrl'
}
}
})
})
Plunkr here
Edit
Can't figure out what i am doing wrong, no view is shown with this code:
app.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) {
// For any unmatched url, redirect to root
$urlRouterProvider.otherwise("/");
$stateProvider
.state('root', {
url: '',
'abstract': true,
views: {
'sidebar#': {
templateUrl: '/App/Main/views/shared/sidebars/sidebar.cshtml',
controller: 'app.controllers.views.shared.sidebars.sidebar',
resolve: {
sidebarData: function (sidebarService) {
return sidebarService.getActions();
}
}
}
},
})
.state('root.home', {
url: "/",
views: {
'': {
templateUrl: '/App/Main/views/home/home.cshtml',
controller: 'app.controllers.views.home'
},
'content#root.home': {
templateUrl: '/App/Main/views/home/home-content.cshtml',
controller: 'app.controllers.views.home'
}
}
})
.state('root.about', {
url: "/customers",
views: {
'': {
templateUrl: '/App/Main/views/customers/customers.cshtml',
controller: 'app.controllers.views.customers'
},
'content#root.about': {
templateUrl: '/App/Main/views/customers/customers-content.cshtml',
controller: 'app.controllers.views.customers'
}
}
});
}]);
and here is how my home and customer views look like:
<div data-ui-view="sidebar">
Loading sidebar view.
</div>
<div data-ui-view="content">
Loading content view.
</div>
you could try to implement named and also an abstract view for your sidebar to reuse it among your other routes, also you can use the resolve parameter an return whatever dynamic data you need (from a service, resource, whatever), it could be something like this:
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider) {
$stateProvider
.state('root',{
url: '',
abstract: true,
views: {
'sidebar#': {
templateUrl: 'sidebar.html',
controller: 'sidebarCtrl',
resolve:{
sidebarData:function(){
return [{
state: '/stateHere',
text: 'Need'
}, {
state: '/stateHere',
text: 'to'
}, {
state: '/stateHere',
text: 'fill'
}, {
state: '/stateHere',
text: 'this'
}, {
state: '/stateHere',
text: 'with'
}, {
state: '/stateHere',
text: 'dynamic'
}, {
state: '/stateHere',
text: 'data'
}];
}
}
}
})
.state('root.home', {
url: "/",
views: {
'content#': {
template: "This is the home.content"
}
}
})
.state('root.about', {
url: "/about",
views: {
'content#': {
template: "This is the about.content"
}
}
})
});
myapp.controller('sidebarCtrl', ['$scope','sidebarData'
function($scope,sidebarData) {
$scope.sidebarData= sidebarData,
}
]);
EDIT:
check this working example:
http://plnkr.co/edit/Nqwlkq1vGh5VTBid4sMv?p=preview