Say i am on a page http://localhost/#/edit/10/step2 and i want to have a link (anchor tag) that takes me to http://localhost/#/edit/10/step1.
What shall one put in ng-href="" and could this be achieved without specifying id (10) in the link?
<a ng-href="step1">Previous</a>
edit (routing):
.config(["$stateProvider", "$urlRouterProvider", "$httpProvider", ($stateProvider: ng.ui.IStateProvider, $urlRouterProvider: ng.ui.IUrlRouterProvider, $httpProvider: ng.IHttpProvider) => {
$urlRouterProvider.otherwise("/home");
$stateProvider
.state("MyModule", {
template: "<div ui-view></div>"
})
.state("home", {
url: "/home",
templateUrl: "App/home.html",
controller: "homeController as ctrl"
});
$httpProvider.interceptors.push("busyHttpInterceptor");
}]);
state (edit):
.state("edit", {
url: "/edit/:id",
templateUrl: "App/edit.html",
controller: "editController",
controllerAs: "ctrl",
resolve: {
}
})
I think you can do the redirection by a ng-click function :
//for the 'state', you can add a new one or edit the existing one depending on your requirement and restirctions
//Add a new one:
.state("edit.action", {
url: "/edit/:id/:action",
templateUrl: "App/edit.html",
controller: "editController",
controllerAs: "ctrl",
resolve: {
}
})
//in the html
<a ng-click=goToAction("step1")>Previous</a>
//in the controller 'editController', inject the service '$stateParams' and '$state'
$scope.goToAction = function(action) {
//get the ':id' from the url
var currentId = $stateParams['id'];
$state.go('edit.action', {
id: currentId,
action: action
});
}
If you want you can also apply regex to the parameter part of the url:
url: "/edit/{id:[a-zA-Z0-9]*}/:action
Related
I have 3 level routing, in url it looks like site.com/Jonny/2. But now I need this looks site.com/2/Jonny or site.com/10/Kelly. But index.name.page it's next page, after index.name, so I can't understand how to swap 3rd and 2nd state. Is it possible?
$stateProvider
.state('index', {
url: '',
controller: 'MainCtrl'
})
.state('index.name', {
url: '#:name',
views: {
'#': {
templateUrl: 'app/names/name.html',
controller: 'NameCtrl'
}
}
})
.state('index.name.page', {
url: '/:number',
templateUrl: 'app/pages/page.html',
controller: 'PageCtrl'
})
inject $state service to your controller, then in your controller...
CONTROLLER
$scope.changeState = function () {
$state.go('where.ever.you.want.to.go', {stateParamKey: exampleParam});
};
and add ng-click to your button
HTML
<button ng-click="changeState()">Change State</button>
I an trying to develop an angular app using ui router, however I am stuck trying to get the controllerAs syntax working correctly.
my stateProvider looks like this
$stateProvider
.state('microsite', {
url: "/",
templateUrl: "microsite.tmpl.html",
abstract: true
})
.state('microsite.home', {
url: "",
templateUrl: "home.tmpl.html",
controller: 'MicrositeController as vm',
data: {
page_name: 'Introduction'
}
})
.state('microsite.features', {
url: "/features",
templateUrl: "features.tmpl.html",
controller: 'MicrositeController as vm',
data: {
page_name: 'Features'
}
})
.state('microsite.about', {
url: "/about",
templateUrl: "about.tmpl.html",
controller: 'MicrositeController as vm',
data: {
page_name: 'About'
}
});
As you can see I setup an abstract default view, and three pages.
I have also assigned a data object with a page_name for each page. This feeds into my controller
myapp.controller('MicrositeController', ['$state', function($state) {
var vm = this;
vm.page_name = $state.current.data.page_name;
vm.sidenav_locked_open = false;
vm.toggleSideNav = function() {
if ($mdMedia('gt-sm')) {
vm.sidenav_locked_open = !vm.sidenav_locked_open;
} else {
$mdSidenav('left').toggle();
}
}
}]);
and then delivers the name to the page via the vm.page_name variable.
However this is not happening. The variable never makes it to the page.
Also I have a vm.toggleSideNav function that is suppose to open and close the sidenav, but that never gets called.
the toolbar with the sidenav button is this
<md-toolbar layout="row" class="md-whiteframe-glow-z1 site-content-toolbar">
<div class="md-toolbar-tools docs-toolbar-tools" tabIndex="-1">
<md-button class="md-icon-button" ng-click="vm.toggleSideNav()" aria-label="Toggle Menu">
XXX
</md-button>
<h1>{{vm.page_name}}</h1>
</div>
</md-toolbar>
here is a plnkr example http://plnkr.co/edit/Na5zkF?p=preview
I am looking for someone to help me figure out the last piece on how to get the toggleSideNav function to get called when I click on the xxx button, and how to get the title to display in the toolbar.
From the Docs:
controller
(optional)
string
function
Controller fn that should be associated with newly related scope or the name of a registered controller if passed as a string. Optionally, the ControllerAs may be declared here.
controller: "MyRegisteredController"
controller:
"MyRegisteredController as fooCtrl"
controller: function($scope, MyService) {
$scope.data = MyService.getData(); }
— UI Router $stateProvider API Reference.
According to the Docs, your controller declaration is correct.
controller: 'MicrositeController as vm'
You need to look for your problem elsewhere.
UPDATE
Put the controller in the root state:
$stateProvider
.state('microsite', {
url: "/",
templateUrl: "microsite.tmpl.html",
//IMPORTANT == Put controller on root state
controller: 'MicrositeController as vm',
abstract: true
})
.state('microsite.home', {
url: "",
templateUrl: "home.tmpl.html",
̶c̶o̶n̶t̶r̶o̶l̶l̶e̶r̶:̶ ̶'̶M̶i̶c̶r̶o̶s̶i̶t̶e̶C̶o̶n̶t̶r̶o̶l̶l̶e̶r̶ ̶a̶s̶ ̶v̶m̶'̶,̶
data: {
page_name: 'Introduction'
}
})
.state('microsite.features', {
url: "/features",
templateUrl: "features.tmpl.html",
̶c̶o̶n̶t̶r̶o̶l̶l̶e̶r̶:̶ ̶'̶M̶i̶c̶r̶o̶s̶i̶t̶e̶C̶o̶n̶t̶r̶o̶l̶l̶e̶r̶ ̶a̶s̶ ̶v̶m̶'̶,̶
data: {
page_name: 'Features'
}
})
.state('microsite.about', {
url: "/about",
templateUrl: "about.tmpl.html",
̶c̶o̶n̶t̶r̶o̶l̶l̶e̶r̶:̶ ̶'̶M̶i̶c̶r̶o̶s̶i̶t̶e̶C̶o̶n̶t̶r̶o̶l̶l̶e̶r̶ ̶a̶s̶ ̶v̶m̶'̶,̶
data: {
page_name: 'About'
}
});
})
The DEMO on PLNKR
Try adding the option controllerAs: 'vm' to the state params instead defining the controller as in the controller option.
Try adding the option controllerAs: 'vm' to the state params instead defining the controller as in the controller option.
or, if I'm not mistaken, you can add
myapp.controller('MicrositeController as vm' ...
Here is my $stateProvider configuration:
.state('itemDetail', {
abstract: true,
url: '/itemDetail/general/:itemid',
controller: 'ItemDetailsController',
templateUrl: './partials/itemDetails.html'
})
.state('itemDetail.general', {
url: "",
controller: 'ItemDetailsController',
templateUrl: "./partials/itemDetails.General.html"
})
.state('itemDetail.file', {
url: "/file/:itemid",
controller: 'ItemDetailsController',
templateUrl: "./partials/itemDetails.File.html"
})
The user can look at item using #/itemDetail/general/96045 and can click the link to look at file attachments. Now it is work but URL for files now is #/itemDetail/general/96045/file/96045.
Is it possible to have URL for files as #/itemDetail/file/96045?
Well, I would go with one parent and only one child state. There is a working plunker
This will be the new one child state itemDetail.type:
.state('itemDetail', {
abstract: true,
url: '/itemDetail',
controller: 'ItemDetailsController',
templateUrl: 'partials/itemDetails.html'
})
.state('itemDetail.type', {
url: "/:type/:itemid",
controller: 'ItemDetailsController',
templateProvider: ['$stateParams', '$templateRequest',
function($stateParams, $templateRequest) {
var url = "partials/itemDetails.General.html";
if($stateParams.type === "file"){
url = "partials/itemDetails.File.html"
}
return $templateRequest(url);
}],
})
We are using here $stateParams.type to decide which template to load (and also $templateRequest to profit from angula built in caching)
And this will be the calling html:
<a ui-sref="itemDetail.type({type:'general', itemid:1})">
<a ui-sref="itemDetail.type({type:'file', itemid:22})">
The url will now look as expected
check it here
Yes it can be you need to give state as
.state('itemDetail.file', {
url: '/{itemId}',
controller: 'ItemDetailsController',
templateUrl: 'partials/itemDetails.html'
})
I have this state:
}).state('sport', {
url: "/:sport",
templateUrl: '/app/sports/sport.tpl.html',
controller: 'SportController',
controllerAs: 'controller'
});
and the controller looks like this:
.controller('SportController', ['$stateParams', function ($stateParams) {
var self = this;
// Object to hold our parameter
self.slug = $stateParams.sport;
}]);
So, what I am trying to do is pass this parameter to another state. Which I have set up like this:
.config(['$stateProvider', function ($stateProvider) {
// Set up our state(s)
$stateProvider.state('sport.designer', {
url: "/designer",
abstract: true,
templateUrl: '/app/designer/designer.tpl.html',
controller: 'DesignerController',
controllerAs: 'controller'
}).state('sport.designer.team', {
url: "",
templateUrl: '/app/designer/team.tpl.html'
}).state('sport.designer.kit', {
url: "/kit",
templateUrl: '/app/designer/kit.tpl.html'
}).state('sport.designer.design', {
url: "/design",
templateUrl: '/app/designer/design.tpl.html'
}).state('sport.designer.refine', {
url: "/refine",
templateUrl: '/app/designer/refine.tpl.html'
}).state('sport.designer.order', {
url: "/order",
templateUrl: '/app/designer/order.tpl.html'
});
}])
and the controller looks like this:
.controller('DesignerController', ['$stateParams', 'DesignerService', 'HttpHandler', 'Api', function ($stateParams, service, handler, api) {
var self = this;
var slug = $stateParams.sport; // Get our slug
console.log(slug);
}]);
So, there are a couple of issues here.
If set up a link like this: ui-sref="sport.designer.team({ sport: controller.slug })" then the view doesn't move from the sport state.
The reason I am using .team is because .designer is an abstract state and the team state is the default state that loads
Here is my html for the sport state:
<a ui-sref="sport.designer.team({ sport: controller.slug })">Test</a>
Can anyone see what I am doing wrong?
I got this working today.
My sport state stayed the same.
I changed the designer states to this:
// Set up our state(s)
$stateProvider.state('designer', {
url: ':sport/designer',
abstract: true,
templateUrl: '/app/designer/designer.tpl.html',
controller: 'DesignerController',
controllerAs: 'controller'
}).state('designer.team', {
url: '',
templateUrl: '/app/designer/team.tpl.html'
}).state('designer.kit', {
url: '/kit',
templateUrl: '/app/designer/kit.tpl.html'
}).state('designer.design', {
url: '/design',
templateUrl: '/app/designer/design.tpl.html'
}).state('designer.refine', {
url: '/refine',
templateUrl: '/app/designer/refine.tpl.html'
}).state('designer.order', {
url: '/order',
templateUrl: '/app/designer/order.tpl.html'
});
and then in my sport.tpl.html I set the link up:
<div class="container">
<div class="row">
<div class="col-md-12">
<h1>{{ controler.slug }}</h1>
<p>This will be the sport homepage.</p>
<p><a ui-sref="designer.team({ sport: controller.slug })">Click to get started</a></p>
</div>
</div>
</div>
and that was it. Designer, did not have to be a child of sport.
Hi I'm trying to dynamically create templates based on the uri eg, contacts/jane would use the template contacts.jane.html
contacts.js
'use-strict';
angular.module('meanApp')
.config(function ($stateProvider) {
$stateProvider
.state('contacts', {
url: '/contacts',
controller: 'ContactsCtrl',
views: {
'': {
templateUrl: 'app/contacts/contacts.html'
},
'list#contacts': {
templateUrl: 'app/contacts/contacts.list.html'
},
'details#contacts': {
templateUrl: function ($stateParams) {
return 'app/contacts/' + $stateParams.id + '.html';
},
controller: function ($scope, $stateParams) {
}
}
}
})
.state('contacts.details', {
url: '/:id',
controller: 'ContactsCtrl'
});
});
contacts.html
<div ng-controller="ContactsCtrl">
<h1>My Contacts</h1>
<div ui-view="details"></div>
<div ui-view="list"></div>
There is a working example. What we need here, is to define the template inside of the child state:
$stateProvider
.state('contacts', {
url: '/contacts',
controller: 'ContactsCtrl',
views: {
'': {
templateUrl: 'app/contacts/contacts.html'
},
'list#contacts': {
templateUrl: 'app/contacts/contacts.list.html'
},
'details#contacts': {
// this could be, filled on a contacts state
// with some default content
template: "place for detail",
}
}
})
// this state has the 'id' defined
// so, here we can decide which template to use
// based on the $stateParams
.state('contacts.details', {
url: '/:id',
views: {
"details": {
controller: 'ContactsCtrl',
templateUrl: function($stateParams) {
url = 'app/contacts/' + $stateParams.id + '.html'
return url;
},
}
}
});
Also, the controller is defined in state so the template contacts should/could for example look like this (no ng-controller):
<div>
<h1>My Contacts</h1>
<div ui-view="list"></div>
<hr />
<div ui-view="details"></div>
</div>
Check that in action here