I am trying to change the route of my url to open a map overlay. The problem is when I switch states, the page template underneath switches as well. I don't want this to happen.
I am using $statechange to detect the map route and executing an event.preventDefault(); which should stop the route template from changing. But in my case, the map url gets put in the address bar and then quickly gets removed.
Any ideas?
It seems counterintuitive to override the state change. Why don't you create the overlay as a child state and just navigate to it normally.
I managed to solve the issue by using the $state.go and declaring options 'notify' to false.. This stops the $stateroute changes to fire.
Related
I am working on an app that has a range of routes that display essentially the same data except the route filters the list based on a status property that determines which entries we want shown in the list.
So in my App.js file I have all the routes set up and the listItems are passed into each of these route components as a property. These items are then rendered out as a table.
Now I have some logic that greys the list out and disabled the buttons on the list items when the list is refreshing using a toggle (isRefreshing) state variable.
The isRefreshing state variable is toggled off using a useEffect() that fires when listItems is updated.
This works great for the refreshing button, but not so well when the route changes.
I've figured out it's because when the route changes the existing listItems prop gets fed into the new rendered list component it see that as listItems changing, so the useEffect() fires, toggling isRefreshing off.
2 seconds later the real data for this new route turns up in the list.
So my question is how can I prevent this from happening? I feel like I might have backed myself into a corner and made a serious architectural error.
Can anyone point me in the right direction?
I've created an example here:
https://codesandbox.io/s/small-sound-rikxv?file=/src/App.js:0-2353
As you can see the refresh button works as expected, but the route change causes the listItems prop to immediately cause my refresh indicator to stop, so you can see a console.log fired immediately after hitting the "list2" link, then 5 seconds later when the real data loads it fires again. The problem is that the initial prop value causes my refresh to stop.
Regards, John.
So I found that if I lifted the "refreshing" state variable right up to the same component the data fetching was happening in then things got a lot easier for me.
Even though the property value changes twice still, because the refreshing state is being handled further up the tree, with refreshing now getting passed down, it's not an issue.
With refreshing getting managed up the tree, the refreshing toggle only gets toggled when refreshing is actually happening and not when the prop thinks it has changed.
Thanks for getting me to code out a simple example, that really helped me conceptualize what was happening free from the clutter of my app's code base.
I am trying to implement conditional rendering for our navbar's items depending on what page we're on (i.e. If we are on the chatrooms page, or "/rooms", then we don't want the "Chatrooms" nav item to render in the navbar). What I attempted to do was convert the Navbar into a class component, create a state for the currentPage and set it to window.location.pathname, and then created methods for setting the state and what nav items to render depending on the state, but it always requires me to reload the page when going from one page to another for the conditional logic to fully take effect. Is there a better way of achieving this functionality?
You could use react-router load content without refreshing the page. It's really simple to learn and use and you could probably get it up and running within an hour. You can Add Route components for the main content of the page.
When you route to a different page you could also call a setState function and change the currentPage, which in turn changes the navbar elements.
If I have something like this:
{ui-sref="tab({tabid:3})"}
Clicking on the element with the above attribute will trigger a state with URL something like this /tab/:tabid.
For example, http://..../tab/3
Now my problem:
I have a list of tabs implemented using angular-material. Refer this plunk
When I click on Tab1 the state is /tab/1. When I click on Tab2 the state is /tab/2. All these state changes occur with click. But now if I manually change the URL, say I type in the address bar http://..../tab/3, I want the corresponding state change to happen and Tab3 should be activated. At present, suppose I am on Tab3 and I manually change the URL to '..../tab/2', it doesn't activate Tab2, although the state is changed.
Is there a simple way to resolve states from the URL by considering the state parameters?
The main concern here is the use of tabs. The first tab belongs to one state and the remaining tabs belong to another state, each tab uniquely identified by an ID that is available through state parameter. So although the correct state is resolved when I manually change the URL, the correct tab is not not made active. The simplest workaround is to read in the state parameter using $stateParams and set the md-selected attribute of angular-material to activate the corresponding tab.
I'm trying to create single page application and one use case is i have details page which can be triggered from multiple parent pages, more like acting as modal box but without any absolute property. I was checking how to show/hide based on the state change from parent.
This is what i have done till now
http://plnkr.co/edit/t34ES8lUihcypetHF0rp?p=preview
If you take a look when clicking View Home from home DOM is not removed while navigating to next state .
But if you are in About Page and click View About, DOM is getting removed.
How can we show/hide ui-view. if we are navigating to different state with same url ?
The same url
url: '^/details/:id',
for both the states is the issue.
Try having a wrapper state say "details" and then in that state's controller you may redirect based on some parameter that tells wrapper state which state to go to.
I'm building a dashboard/control panel app that is basically made up of two tabs (bootstrap) at the root level, called "dispatch" and "admin". Each tab has a good bit of its own multi-tiered navigation and functionality, and they don't need to directly interact with each other. The problem I'm running into is how to deep-link to sub-views within one of the tabs without losing the "state" of the inactive tab. To clarify, I can achieve this just fine if I don't worry about updating the URL, but when I try to add deep-linking, that's when I get stuck.
An example of the desired behavior:
When you click on the "Admin" tab, the route becomes "/admin"
Click on a sub-nav item, route becomes "/admin/foo"
Select 3rd-tier sub-level item, route becomes "admin/foo/thing1"
Click on the "dispatch" tab, route becomes "/dispatch"
Click back on the "admin" tab, route goes back to "admin/foo/thing1"
So basically, if you're at the "admin/foo/thing1" route in the middle of filling out a text field, then switch to another tab, then switch back, the text field should still be there just as you left it.
Like I said, the problem isn't switching from tab to tab, since by default the tabs just show and hide things on the page without reloading any views dynamically. I just don't know how to deep-link to a given tab's "bookmarked" position when you switch to it. The way I keep thinking of it is that clicking on a tab should only update the first segment of the URL(/admin or /dispatch), and then some sort of $watch function would update the remaining segments based on the last "location" within that tab. Would something like that work?
Also, I'm using ui-router to handle all my routing and states, so I have to factor that into how I'm going to handle the desired behavior.
Help?
I worked on both those topics (deep state reactivation and parallel states) and integration into ui-router. Grab my github fork of ui-router and build using grunt. Then, mark your two tab states as parallel: true and deepStateRedirect: true.
Git repo: https://github.com/christopherthielen/ui-router
Example plunker: http://plnkr.co/edit/YhQyPV?p=preview
Discussion: https://github.com/angular-ui/ui-router/issues/894
I would just save the current state in a variable, then either dynamically change the link of the tab to whatever the last subview was.
For example, if the user is on /admin/billing, the Admin tab would link to admin/billing. When they leave that tab, the /admin tab remains the same. If you are using ui-router, you can do this with ui-srefs. You could also just manually check the variable when the state changes, and route the user there from the controller.