How to add external link to Angular SPA Menu? - javascript

I'm using angular hottowel template for develop my web application. route config code file shown bellow.
(function(){
'use strict';
var app = angular.module('app');
// Collect the routes
app.constant('routes', getRoutes());
// Configure the routes and route resolvers
app.config(['$routeProvider', 'routes', routeConfigurator]);
function routeConfigurator($routeProvider, routes)
{
routes.forEach(function(r)
{
setRoute(r.url, r.config);
});
$routeProvider.otherwise({ redirectTo: '/' });
function setRoute(url, definition)
{
definition.resolve = angular.extend(definition.resolve || {}, {
prime: prime
});
$routeProvider.when(url, definition);
}
}
prime.$inject = ['datacontext'];
function prime(dc) { return dc.prime(); }
// Define the routes
function getRoutes()
{
return [
{
url: '/',
config: {
templateUrl: 'app/dashboard/dashboard.html',
title: 'dashboard',
settings: {
nav: 1,
content: '<i class="fa fa-dashboard"></i> Dashboard'
}
}
}, {
url: '/customers',
config: {
title: 'customers',
templateUrl: 'app/customer/customers.html',
settings: {
nav: 2,
content: '<i class="fa fa-calendar"></i> customers'
}
}
},
{
url: '/customer/:id',
config: {
title: 'customer',
templateUrl: 'app/customer/customerdetail.html',
settings: {}
}
}
];
}})();
I need to add external link to my menu as example www.google.com. how can i add another link to this route config like bellow.
{
url: 'www.google.com',
config: {
title: 'MyExternalLink',
settings: {}
}
}

This question looks similar to this post have a look
Using $routeProvider to redirect to routes outside of Angular

Related

Is it possible to combine ion-tree-list with a navigation view?

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')

Access a service in AngularUI Router onEnter callback

Im using Angular 1.5.6 and am using AngularUI Router (https://github.com/angular-ui/ui-router). I have different routes e.g. customer and users. In each of these there are different 'sub-roots' e.g. one for list and one for edt. Im setting up the customer route here:
import customerListModule from './list/customer.list';
import customerServiceModule from './services/customer.service';
...
...
function customerModule($stateProvider, $urlRouterProvider) {
'ngInject';
$urlRouterProvider
.when('/customer', ['$state', function($state) {
$state.go('customer.list.tracked');
}]);
$stateProvider
.state('customer', {
parent: 'root',
url: '/customer',
abstract: true,
views: {
'root#app': {
template: '<div class="customer" ui-view=""></div>'
}
},
onEnter: () => {
// in here I want to change my customer servce
},
})
.state('customer.list', {
url: '',
views: {
'#customer': {
template: '<customer></customer>'
}
},
breadcrumbs: {
name: 'customer.breadcrumbs.list'
},
params: {
saving: false
}
})
.state('customer.edit', {
parent: 'customer.list',
url: '/:id/edit',
views: {
'#customer': {
template: editTemplate(),
controller: manageCustomerCtrl,
controllerAs: 'manageCustomerVM'
}
},
breadcrumbs: {
name: 'customer.breadcrumbs.edit'
},
resolve: {
isAuthorized: 'readWriteAccess'
},
bodyClass: 'product-form'
});
}
export default angular.module('customerAdminUI.customer', [
'ui.bootstrap',
'ui.router',
customerListModule.name,
customerServiceModule.name,
...
...
])
.config(customerModule);
I have a customer service which I want to access in the onEnter callback of the customer state. I tried to inject it into the customerModule method so that I can use it in the onEnter() callback:
function customerModule($stateProvider, $urlRouterProvider, CustomerService) {
...
...
$stateProvider
.state('customer', {
parent: 'root',
url: '/customer',
abstract: true,
views: {
'root#app': {
template: '<div class="customer" ui-view=""></div>'
}
},
onEnter: () => {
CustomerService.clearSearch();
},
})
However I get the error:
Unknown provider: CustomerService
How can I use a service in the onEnter callback?
We can ask for a service as a param
// not ready for minification
onEnter: function(CustomerService) {
CustomerService.dowhatneeded...
},
// preferred way
onEnter: ['CustomerService', function(service) {
service.dowhatneeded...
}],

AngularJs - changing from ngRoute to ui-router throwing Error: [$injector:unpr]

I changed the routing in my app from ngRoute to ui-router,i am getting two errors:
SyntaxError: Unexpected string
Uncaught Error: [$injector:unpr]
config.route.js:
(function () {
var app = angular.module('app');
//Collect the routes
app.constant('routes', getRoutes());
app.config(['$stateProvider', '$urlRouterProvider', 'routes', routeConfigurator]);
function routeConfigurator('$stateProvider', '$urlRouterProvider', routes) {
routes.forEach(function (r) {
$stateProvider.state(r.url, r.config);
});
$urlRouterProvider.otherwise('/');
}
//Define the routes
function getRoutes() {
return [
{
url: '/',
config: {
templateUrl: 'app/components/dashboard/test/dashboard.html',
title: 'dashboard',
settings: {
nav: 1,
content: '<i class="fa fa-dashboard"></i> Dashboard'
}
}
}, {
url: '/admin',
config: {
title: 'admin',
templateUrl: 'app/components/admin/admin.html',
settings: {
nav: 2,
content: '<i class="fa fa-lock"></i> Admin'
}
}
}
];
}
})();
Previously it was as follows and working fine:
app.config(['$routeProvider', 'routes', routeConfigurator]);
function routeConfigurator($routeProvider, routes) {
routes.forEach(function (r) {
$routeProvider.when(r.url, r.config);
});
$routeProvider.otherwise({ redirectTo: '/' });
}
The ui-router module is referenced correctly in app.js, angular-ui-router.min.js file is loading successfully on index.html loading. What am i doing wrong ? Please help !
function routeConfigurator('$stateProvider', '$urlRouterProvider', routes)
should be
function routeConfigurator($stateProvider, $urlRouterProvider, routes)
That is why you get a Unexpected string error.
The second error is a consequence of the first.

Angular ui.router dynamic sidebar

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

angularjs $routeProvider route is executed before resolve completes

I would like the route.resolve method(s) to fire before the actual route code is run. Unfortunately in the code below, prime() gets called but it is called asynchronously and the route code gets called before the prime completes. I thought the resolve methods of a route was suppose to complete before the route is loaded?
(function () {
'use strict';
var app = angular.module('app');
// Collect the routes
app.constant('routes', getRoutes());
// Configure the routes and route resolvers
app.config(['$routeProvider', 'routes', routeConfigurator]);
function routeConfigurator($routeProvider, routes) {
routes.forEach(function (r) {
setRoute(r.url, r.config)
});
$routeProvider.otherwise({ redirectTo: '/' });
function setRoute(url, definition) {
//set resolvers for all of the routes
//by extending any existing resolvers (or creating a new one)
definition.resolve = angular.extend(definition.resolve || {}, {
prime: prime
});
$routeProvider.when(url, definition);
return $routeProvider;
}
}
prime.$inject = ['datacontext'];
function prime(dc) {
dc.prime();
}
// Define the routes
function getRoutes() {
return [
{
url: '/',
config: {
templateUrl: 'app/dashboard/dashboard.html',
title: 'dashboard',
settings: {
nav: 1,
content: '<i class="icon-dashboard"></i> Dashboard'
}
}
},
{
url: '/sessions',
config: {
title: 'admin',
templateUrl: 'app/sessions/sessions.html',
settings: {
nav: 2,
content: '<i class="icon-calendar"></i> Sessions'
}
}
},
{
url: '/speakers',
config: {
title: 'speakers',
templateUrl: 'app/speakers/speakers.html',
settings: {
nav: 3,
content: '<i class="icon-user"></i> Speakers'
}
}
},
{
url: '/attendees',
config: {
title: 'attendees',
templateUrl: 'app/attendees/attendees.html',
settings: {
nav: 4,
content: '<i class="icon-group"></i> Attendees'
}
}
}
];
}
})();
Try changing prime to the following:
function prime(dc) {
return dc.prime();
}
I suggest you re-position the prime function to the global controller defining it as:
$scope.prime = function (dc) {
dc.prime();
};
Move prime inside scope of routeConfigurator
(function () {
'use strict';
var app = angular.module('app');
// Collect the routes
app.constant('routes', getRoutes());
// Configure the routes and route resolvers
app.config(['$routeProvider', 'routes', routeConfigurator]);
function routeConfigurator($routeProvider, routes) {
routes.forEach(function (r) {
setRoute(r.url, r.config);
});
$routeProvider.otherwise({ redirectTo: '/' });
function setRoute(url, definition) {
definition.resolve = angular.extend(definition.resolve || {}, { prime: prime });
$routeProvider.when(url, definition);
return $routeProvider;
}
prime.$inject = ['datacontext'];
function prime(datacontext) {
return datacontext.prime();
}
}
// Define the routes
function getRoutes() {
return [
{
url: '/',
config: {
templateUrl: 'app/dashboard/dashboard.html',
title: 'dashboard',
settings: {
nav: 1,
content: '<i class="fa fa-dashboard"></i> Dashboard'
}
}
},
{
url: '/sessions',
config: {
title: 'sessions',
templateUrl: 'app/sessions/sessions.html',
settings: {
nav: 2,
content: '<i class="fa fa-calendar"></i> Sessions'
}
}
},
{
url: '/speakers',
config: {
title: 'speakers',
templateUrl: 'app/speakers/speakers.html',
settings: {
nav: 3,
content: '<i class="fa fa-user"></i> Speakers'
}
}
},
{
url: '/attendees',
config: {
title: 'attendees',
templateUrl: 'app/attendees/attendees.html',
settings: {
nav: 4,
content: '<i class="fa fa-group"></i> Attendees'
}
}
}
];
}
})();

Categories