I have made yoman angular fullstack app setup.
I am making use of ui.router in application.
I have defined state parameters as
.state('tour', {
url: '/tour',
templateUrl: 'app/tour/tour.html',
controller: 'tourCtrl',
params : {tourName: null, },
})
I am able to pass parameter to this state within application.
when my application goes to external link.
I want to get back to one of the state of my angular application with some parameter. so how can i do that??
Please Help me to do that .. Thanks
you can pass parameters and maintain states using stateParams, and then maintaining them in the URL. For your understanding, I have added a plunk:
http://plnkr.co/edit/SDOcGS?p=preview
Observe the console whenever you navigate to Route1 tab, and then observe the code:
.state('route1', {
url: "/route1/:place",
params: {
place: null
},
views: {
"viewA": {
template: "route1.viewA"
},
"viewB": {
template: "route1.viewB"
}
},
resolve :{
place: function($stateParams){
console.log($stateParams);
console.log("url", window.location);
return $stateParams.place;
}
}
})
Try this on localhost. It would work the same way on localhost, or any place where its hosted.
Related
I have an application with a main state and a child state. I do have the url property set but it seems angular it is ignoring it, but it is not ignoring the optional parameter at the end, which is correctly populated. Please see below code snippet. (to be honest, this application always worked but after an update in the Siemens product this particular feature is not behaving correctly, but at the end of the day this is an angular app, so I am not sure how they could have changed globally this behavior if you have an idea I will be very happy to check that). thanks
this is the main page:
function config($stateProvider) {
var item = {
name: "Carriers",
//ShippingAndReceiving is ignored, but /:direction is correclty attached to the URL
url: '/ShippingAndReceiving/:direction',
views: {
'Canvas#': {
templateUrl: folder + '/carrierOverview.html',
controller: 'CarrierOverviewController',
controllerAs: 'vm'
}
},
data: {
title: 'Vehicles'
},
params: {
reload: null,
carrier: null,
direction: null,
arriving: null
}
};
$stateProvider.state(item);
}
this is the child page:
function config($stateProvider) {
var item = {
name: 'Carriers.Details',
url: '/RegisterVehicle',
};
$stateProvider.state(item);
}
both the pages load correctly and everything works properly, but the URL does not change, it is constantly "Carriers" for both pages.
I do not have any extra unnecessary $state.go anywhere.
this is the call to browse to the page:
$state.go('Carriers.Details');
I'm using Angular and UI router. I'm trying to get a link shown on the page that the user can copy and share. This thread has shown me that $state.href is the function I'm looking for, however it isn't generating the correct link.
An important detail here is that the root of my application is not the root of the domain. In this case, the domain is localhost, but the root of the angular app is in localhost/dev/app/.
Here's the command I'm using inside my controller.
$scope.url = $state.href('survey', { survey: "asd" }, {absolute: true});
In my app.js, the following route is declared:
.state('survey', {
url: "/:survey/survey?ao",
templateUrl: "views/survey/survey.html",
controller: "surveyController",
},
data: {
requireLogin: false,
requireAdmin: false
}})
This should return http://localhost/dev/app/#/asd/survey, instead it returns http://localhost/#/asd/survey.
(The remarkable thing is that ui-sref="survey({survey: "asd"}) does translate to the correct link.)
Is there a way I can fix this so I get the full url?
Adding a base tag to my app page solved this issue for me. It defines the base URL for the page with the router references. For legacy support reasons, I'm on version 0.2.15 of Angular UI Router. I don't know if this is still necessary for more current versions.
<base href="http://localhost/dev/app/" />
.state('survey', {
url: "/:survey/survey?ao",
templateUrl: "views/survey/survey.html",
controller: "surveyController",
data: {
requireLogin: false,
requireAdmin: false
}
})
You had an extra '},' in after controller, maybe that is messing things up? Also if you're passing parameters you might want to include that as a params line:
params: {
survey: null
}
Also if you want the url http://localhost/dev/app/#/asd/survey your url should be:
url: "dev/app/:survey/asd/survey"
Get the context, angular, ui-router, nothing special, a root view built with 3 named ui-views.
so in index.html we have
<body>
<div ui-view='left'>
<div ui-view='center'>
<div ui-view='right'>
</body>
my route looks like
$stateProvider
.state('main', {
url: '/',
views: {
'left': {templateUrl: 'foo.html'},
'center': {templateUrl: 'bar.html'},
'right': {templateUrl: 'xyz.html'}
}
})
.state('main.b', {
url: '/b',
params: { foo: {value: 'bar'} }
views: { 'right#': {templateUrl: '123.html'} } // I wish to update $stateParams in 'left#' view
})
.state('main.c', {
url: '/c',
params: ...
views: { 'left#': ..., 'center#': ..., 'right#': .. }
});
Is there a way in going to b state to update the $stateParams in the 'center' and 'left' view?? I can get it using a service but i need to add a $watch to the variable I need and it looks a little bit hacky to me.
Going into c state I can actually get what I want, but the view is reloaded, and i wish to avoid this behaviour cause i have a canvas in the 'left' view.
You could use the following to go to a specific route without reloading the views:
$state.go('.', {parm1: 1}, {notify: false});
The last object literal represents the options which you can pass along to go. If you set notify to false, this will actually prevent the controllers from being reinitialized. The . at the beginning is the absolute state name or relative state path you wanna go to.
The important thing is the notify though.
I think that using "Dynamic params" is now a better solution:
When dynamic is true, changes to the parameter value will not cause the state to be entered/exited. The resolves will not be re-fetched, nor will views be reloaded.
$stateProvider.state('search', {
url: '/search?city&startDate&endDate',
templateUrl: 'some/url/template.html',
params: {
city: {
value: 'Boston',
dynamic: true
}
}
}
and then:
$state.go('.', {city: 'London'});
https://ui-router.github.io/ng1/docs/latest/interfaces/params.paramdeclaration.html#dynamic
https://github.com/angular-ui/ui-router/issues/2709
Quoting #christopherthielen from https://github.com/angular-ui/ui-router/issues/1758#issuecomment-205060258:
using notify: false is almost never a good idea, and is now
deprecated. Use reloadOnSearch if you must.
You can also try dynamic parameters in the 1.0 version (currently
1.0.0-alpha.3). In your state, configure a parameter as dynamic and implement the uiOnParamsChanged callback :
.state('foo', {
url: '/:fooId',
params: { fooId: { dynamic: true } },
controller: function() {
this.uiOnParamsChanged = function(changedParams, $transition$) {
// do something with the changed params
// you can inspect $transition$ to see the what triggered the dynamic params change.
}
}
});
For a demo, have a look at this plunker: http://plnkr.co/edit/T2scUAq0ljnZhPqkIshB?p=preview
I'm making a single page application (SPA). I made a controller called InitialControler to load the data from the server at this url (local.app/init).
I want this url to be opened before any other url. I'm using ui-router, I did a $state.go('init') in the .run() function but it still load the requested page before the 'init' page
First create state called app
$stateProvider.state('app', {
abstract: true,
templateUrl: "assets/partials/container.html",
controller: 'AppCtrl',
resolve: {
init: function(MyFactory) {
return MyFactory.resolver();
}
}
});
Now, any new state you create should be child state of app state. This is also good because it become sort of your root scope. And state will not process unless your factory resolves.
This is how you create your factory
app.factory('MyFactory', function($http){
var items = [];
return {
resolver: function(){
return $http.get('my/api').success(function(data){
items = data;
})
},
get() {
return items;
}
}
});
Now in any other state
$stateProvider.state('app.items', {
url: '/items',
templateUrl: "assets/partials/items.html",
controller: function($scope, MyFactory){
$scope.items = MyFactory.get();
}
});
More on sate resolve
https://github.com/angular-ui/ui-router/wiki#resolve
If you are using ui-router then you could resolve this using nested states. For example:
$stateProvider
.state("main", {
url: "/",
template: '<div ui-view></div>',
controller: 'InitController'
})
.state("main.landing", {
url: "landing",
templateUrl: "modules/home/views/landing.html",
controller: 'LandingPageController'
})
.state("main.profile", {
url: "profile",
templateUrl: "modules/home/views/profile.html",
controller: 'ProfileController'
});
In this example you have defined 3 routes: "/", "/landing", "/profile"
So, InitController (related to "/" route) gets called always, even if the user enters directly at /landing or /profile
Important: Don't forget to include <div ui-view></div> to enable the child states controller load on this section
One way to do is, in config declare only 'init' state. And in InitialController, after data is loaded(resolve function of service call), configure other states. But in this approach, whenever you refresh the page, the url will change to local.app.init.
To stay in that particular state even after reloading, the solution I found is to have a StartUp app in which I loaded the required data and after that I bootstraped the main app manually by angular.bootstrap.
I've been looking at these pages (1, 2, 3). I basically want to change my $state, but I don't want the page to reload.
I am currently in the page /schedules/2/4/2014, and I want to go into edit mode when I click a button and have the URL become /schedules/2/4/2014/edit.
My edit state is simply $scope.isEdit = true, so there is no point of reloading the whole page. However, I do want the $state and/or url to change so that if the user refreshses the page, it starts in the edit mode.
What can I do?
For this problem, you can just create a child state that has neither templateUrl nor controller, and advance between states normally:
// UPDATED
$stateProvider
.state('schedules', {
url: "/schedules/:day/:month/:year",
templateUrl: 'schedules.html',
abstract: true, // make this abstract
controller: function($scope, $state, $stateParams) {
$scope.schedDate = moment($stateParams.year + '-' +
$stateParams.month + '-' +
$stateParams.day);
$scope.isEdit = false;
$scope.gotoEdit = function() {
$scope.isEdit = true;
$state.go('schedules.edit');
};
$scope.gotoView = function() {
$scope.isEdit = false;
$state.go('schedules.view');
};
},
resolve: {...}
})
.state('schedules.view', { // added view mode
url: "/view"
})
.state('schedules.edit', { // both children share controller above
url: "/edit"
});
An important concept here is that, in ui-router, when the application is in a particular state—when a state is "active"—all of its ancestor states are implicitly active as well.
So, in this case,
when your application advances from view mode to edit mode, its parent state schedules (along with its templateUrl, controller and even resolve) will still be retained.
since ancestor states are implicitly activated, even if the child state is being refreshed (or loaded directly from a bookmark), the page will still render correctly.
REF: https://github.com/angular-ui/ui-router/wiki/Quick-Reference#statetransitiontoto-toparams--options
$state.transitionTo('yourState', params, {notify: false});
Adding my answer because I think it's different enough from the accepted answer and may be useful to others:
I had two states, begin and view, with a bunch of optional parameters being synced with the URL for view, like so:
$stateProvider
.state('begin',
{
url: '/',
template: '<app-element></app-element>'
})
.state('view',
{
url: '/View?param1¶m2&...¶mN',
template: '<app-element></app-element>'
params: {
param1: {
value: null,
squash: true
},
...
}
});
The link function for <app-element> would run any time I tried to sync the parameters using $state.go. Using {notify: false, reload: false} did not work for me. The link function still ran each time. I'm on 0.2 so dynamic isn't an available param option, either. I followed #b0nyb0y's suggestion and turned it into a parent/child relationship, which worked:
$stateProvider
.state('app',
{
url: '/',
template: '<app-element></app-element>'
})
.state('app.view',
{
url: 'View?param1¶m2&...¶mN',
params: {
param1: {
value: null,
squash: true
},
...
}
});