I'm working on an app in which user first select an item then get tabs related to actions available for this item.
In order to keep thing simple (and also because I'm not sure how to do otherwise) I pass the object id in the href of the tab so you have /{object_id}/tab1
The tab menu is created by the following :
.state('check', {
abstract: true,
url: "/check/:eventId",
templateUrl: "templates/check_menu.html",
controller: 'checkMenuCtrl'
})
It works perfectly for the first item, but if I go back to the menu and select another object, the href links of the tab menu are still with the first id.
It looks like the $stateParams.object_id used to populate tabs href is never updated.
.controller('checkMenuCtrl', function($rootScope, $scope, $stateParams) {
$scope.eventid=$stateParams.eventId;
})
Any idea of how I could do that ?
Thank you by advance for your help !!
Looks like abstract controlers are never updated.
$stateParams are updated in services (factory) so it's the better solution I found so far !
Related
I have the following code redirect/transition logic in my appConfig for re-pointing of invalid routes:
$urlRouterProvider.when('/:lang/profile/:keywords/:id', ['$state', '$stateParams', function ($state, $stateParams) {
$state.transitionTo('root.public-profile.summary', $stateParams, {
reload: true,
inherit: false,
notify: true
});
with Summary route defined as:
state('root.public-profile.summary', {
url: "/summary",
templateUrl: "/templates/public.profile.summary.tpl.html"
})
So when a user attempts to access '/:lang/profile/:keywords/:id' it should redirect/re-point them to /:lang/profile/:keywords/:id/summary. This works fine when a view had been loaded before, if a user attempts to remove the 'summary' portion from the Url, it does gets re-appended automatically as expected. However, if a user copies and pastes 'wrong' link directly in a new browser window, the $stateParams object is empty and thus transition can't happen.
Is that behavior by design and is there a way to fix that?
You are right Val,
This behaviour is by design.You should see everything in the form of state-diagrams and Whether the transition will happen or not depends on what state is getting activated.What I can see from your snippet is that here you are working with ui-router where states carries more significance then the actual urls.
Not sure what you are trying to achieve but these docs can be helpful to you.
https://github.com/angular-ui/ui-router/wiki
Please Comment back for any other concerns or vote up if you are convinced with this answer.
I'm using ui-router for my page routing in my AngularJS app. I'm encountering an issue where if I click a hyperlink on a page that refers to the page/route I'm already on (i.e. self), nothing will happen.
For example, if you're scrolled halfway down a page and you click a hyperlink that refers to the current page, it will seem as though the link doesn't load, when in actual fact nothing needs to be loaded as the user is already on the right page.
The goal in this situation is to have the viewport moved to the top of the page, but I cannot get any event from ui-router for this event. I've tried $stateChangeStart and $stateChangeSuccess, but as no route change occurs, these do not fire.
My urls are of the form http://localhost:3000/projects/myproject and ui-router is configured as follows:
state('app.projects', {
url: '/projects/:projectname',
templateUrl: 'projects.html',
controller: 'ProjectsCtrl'
}).
Without adding extra logic in the controller (which would obfuscate the natural href="projects/myproject" format), what can be done to achieve this?
Without controller:
<a ui-sref="stateName({reload: true})" target="_blank">Link Text</a>
With controller:
$state.go($state.name, {}, {reload: true});
You can simply use # at the end of the link. href="projects/myproject#"
I have a page as shown in this plnkr example.
http://plnkr.co/edit/NKVVn4ga6lYOBWEblt0o?p=preview
When I click on a hyperlink(added on bottom of page) with href="#/test", I want it to open this page but with the one of the items in the list selected.
(The reason for trying to acheive this is I will have a url with this route in a different app and when clicking on the link I want this page open with the item selected.)
This is what my routeProvider code looks like
myItemsApp.config(['$routeProvider', function($routeProvider){
$routeProvider.
when('/test',{
templateUrl:'index.html',
}).
otherwise({
redirectTo:'/',
})
}]);
Can I do anything in here to set the third item (for example) in the list selected?
What I have done so far is I have tried doing a resolve in the routeProvider and some logic in the controller to set the third item in the list to be selected and has failed miserably.
Any help would be greatly appreciated.
this is actually very simple, if you already have your route just use $routeParams
to get the handle on the selected item id and then use that id to traverse your list and set the right element as active, as for your route, i don't recall ngRoute cause i haven't use it in a while, but you can just create other route, same controller, same template just make the url look like /test/:item_id
I have a nested state structure like this:
$stateProvider
.state('main', {
url: '',
abstract: true,
templateUrl: ...
controller: mainController,
resolve: {
Resolve1: ...
Resolve2: ...
}
})
.state('main.state1', {
url: '^/state1/:id/',
templateUrl: ....
controller: state1Controller,
resolve: {
Resolve11: ...
Resolve22: ...
},
})
.state('main.state2', {
....
From what I am seeing, when you are at state main.state1 and you navigate to the same state with another id parameter, the template for main.state1 is rendered fine but the template for main (the parent) is rendered before the state changes (I guess it doesn't wait for the data resolution of main.state1). This results to the view being rendered with the wrong data (more specifically, the state parameters that I use for generating links are wrong).
My mainController has the $stateParams and $state injected to it and that's where I get the data from.
Did anyone notice this before? Is this by design or is it a bug?
Is there any way to update the parent view with the latest data?
However, I would expect ui-router to wait for all data resolutions until it starts rendering the views (even the parent). I don't know if I am missing something here, but this is my understanding of the problem so far...
UPDATE:
I see now that a function that is involved in the view rendering (with interpolation) gets called many times, first with the old values and then with the new values. But the final result that I see on screen is using the initial data that were used when I first entered the 'main.*' state. This is SO weird.
UPDATE 2:
I have found that my links where not updated ONLY when using ui-sref (note that I was using parameters in the state href, e.g. ui-sref="main.state1({id:{{getId()}}})"). When switched to ng-href everything worked as expected.
I have no idea why, but that fixed the problem.
The odd thing was that the ui-sref was evaluated, but the link was not updated.
Go figure...
UPDATE 3:
This solution in turn caused other problems. Then the first click reloaded the application... So this is not the best fix...
The "solution" was to use ng-click with $state.go(), instead of links.
This appears to be a bug in ui-router.
ui-router transitions "through" the parent state to the child. That means main will be triggered, then main.state1. I ran into this myself where I was getting duplicate listeners and HTML DOM elements - main is actually running AT THE SAME TIME as main.state1. This behavior is by design, and AFAIK your only option is to design around it.
I was thinking last night about how to port our crud application to a tab based app, like gmail. First, reading a lot about ui-router, i thought in create a tabService that will create a new tab for each state change (listen $rootScope.stateChangeSuccess), the new tab would include the corresponding view (ui-view="bancos") that will display the state template.
My first test and my first problem, when shown the list of items, a click over one of the item (itemId=4 for example) should open a new tab and display the item with id=4 in this tab, inside the corresponding (ui-view="bancos/4"). Note how i'm trying to map named ui-view with states to display the state defined templates in the corresponding ui-view.
I know that ui-router sample seems to do what i'm trying, but they are using nested states with unamed ui-view inside parent state template. In my case, the parent state ui-view element and his child state ui-view element should be sibling.
Considering the nature of angular, tree structured, and the nature of ui-router states, tree structured too, can i use ui-router to implement my requirements (crud application with tab based design).
Regards
Danny
Here is me example, if you have questions i can answer
http://plnkr.co/edit/tqfPVFaesSe9Q6ZkPMzE?p=preview
Short explain: don't use tabs instead of that create a fake, works well and you save a lot of work.
Best
I was looking for the same info, does the following example help you?http://plnkr.co/edit/gMsKK9l7J0B8vZIMIVfD?p=preview (Not my coding.)
Edit:
I've found more useful data.
https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
In my code, I have set it up like this:
.state('surveys.list', {
url: '/list',
templateUrl: "survey/surveys_overview.tpl.html",
controller: 'SurveyOverview'
})
.state('surveys.create', {
abstract: true,
templateUrl: "survey/survey.create.tpl.html",
controller: 'SurveyManageController'
})
.state('surveys.create.views', {
url: '/create',
views: {
'details': {
templateUrl: "survey/survey.create.details.tpl.html"
},
'steps': {
templateUrl: "survey/survey.create.steps.tpl.html"
}
}
});
The surveys.create.tpl.html just has a and two tabs with each one div:
<div ui-view="details"> & <div ui-view="steps">