I have a list of items in #/xxx which when clicked will pop up a lightbox and change the hash to #/xxx/yyy. In the lightbox, there's a "Back" button. How do I revert to previous page (i.e. "#/xxx")? I'm looking for something like "Backbone.back()". This action must not trigger the route handler (otherwise the list of items will be empty since it's an Ajax search result).
There's two easy ways I can think of doing this:
1) Make the "back" button not really go back at all, just repeat the previous route (the one prior to bringing up the lightbox) again. Then going backwards and forwards through the history will produce the results you expect to see.
2) Just tell the browser to step back one step within the history. You can do that in JavaScript like so:
window.history.back();
Results should be just like the other way of doing the same thing.
Related
I've often come across a situation where I have a list of items in my store (loaded at "boot") and I'm implementing an "edit item view". There are numerous ways to do this but I've yet to find one that really feels solid given a few "constraints".
My edit view "constraints":
The selected item must be copied to its own reducer (activeItem). This is
to a) give me a comparison point so I can tell the user if the item
has changed or not) and b) in some cases, it allows me to update the
main item list without affecting the edited item
I want the URL to reflect that I'm editing an item and obviously
directly navigating to the item should work (I typically use React-Router)
If I have an "editItem" action, 1 is easy but fulfilling 2 feels hacky. I need to parse URL params, await that the main list is loaded and then call editItem. A bit of a mess.
If I accept that the URL should be the source of truth for active item, 2 is easy but I'll have to manage a bit more state in my edit component to do 1 (check if an active item is, and if not, dispatch an editItem action.
Is there a good, clean pattern I'm missing?
(Third approach would be to use URL as the source of truth for active item and never "copy" the item over. This means I don't have a comparison point for "has user changed this" though and doesn't allow me to update the "main list" in the background).
To me it makes sense to only use the redux store for data which is (or at some point in the future may need to be) accessed from different parts of the app. This helps keeps the structure of the store clean and easy to understand.
Temporary activeItem fields etc on the store which will only be looked at by a single display component over a single component lifecycle just add bloat, when this data could be nicely tucked away on the state of the only interested component.
Therefore I vote to keep the URL as the source of truth for the active item, and for letting the edit component keep a copy of the original version and perform any "has been changed" checks itself. I would say this is preferable regardless of the added plus of simple direct linking to your URL.
So I have been plowing the internet to understand or see and example of what I want to do.
It shouldn't be difficult, but something is just missing to me.
The Scenario
I have a search page, built from 2 directives/ ui-views like this:
What I want to achieve
When I press Search, I want to trigger the Search Results directive/ view to fetch the corresponding results based on the search form parameter.
Where I am stuck
Because I have 2 separate directives, I can make them share information using the parent controller, OR the search service I have (to communicate with the backend).
However, The search directive can write information to either one, BUT the results are still not triggered. Unless I actively check for changes every once in a while for changes, I won't get the cling saying I have been triggered.
That is definitely not the the AngularJS way, and I just don't seem to have enough experience to think of something else.
What I am asking you
How would you approach this situation, what will you use to make this page as clean as you can, and modular (of course).
I've had ideas that at the worst case scenario, I will omit the modular approach, and just do it dirty, but working.
Still, this annoys me because as far as I know, this is one of the STRONGEST features of Angular.
I'd appreciate if you could attach some code for all to see and learn
As far as I see, this page is turning around of search functionality. So what I suggest you to implement here - to include search text into your routing parameters.
Your Search box which is help user to write down search query. Make it add search query to routing as some parameter, once user click Search button. It will be the only one responsibility of Search box, to change location URL, literally.
Action: User wrote down Founder in the search box input and pressed button Search.
Result: Location changed from #/search/ to #/search/Founder
The search result view should just respond to the location change. If the search string is changed, it should do all needed calls to the server, and return, process and represent search result in the Search result block.
I have a page that user can make changes to an item like changing title, description and etc, after user made the changes and they are saved, he can travel away from the website, then goes back using the 'Back' button and what he sees is the page actually before the changes he has made.
The reason for that, instead of actually making GET request for the item, Chrome returned request from the cache instead, you can see it in Network tab in the Size column as (from cache).
One of the solutions that colleague of mine proposed is to append query parameter with some random integer to request, but it's kinda hacky.
Do you take care of this situation, if yes then how or why not?
I have an apex page which relies heavily on rerendering certain parts of the page. The issue is that when I click on a commandbutton, normally it calls its action method, and rerenders a part of the page, however, it only works about half the time. On the other occasions the action method does not fire. (Something still happens, because it creates a debug log)
The confusing thing about it is that it happens seemingly randomly (e.g. It works, I reload the page, then it doesn't work, while nothing changed)
Unfortunately I don't have permission to post the code, but any idea would be appreciated.
It was caused by an actionsupport tag inside of a commandbutton which I think should be fine, but it wasn't. I deleted the actionsupport, edited the button itself to contain the rerender and action attributes, and now it works.
According the docs:
In iOS 6 and later, if you assign a value to this view’s restorationIdentifier property, it attempts to preserve its URL history, the scaling and scrolling positions for each page, and information about which page is currently being viewed. During restoration, the view restores these values so that the web content appears just as it did before.
I'm doing all that, but nothing is happening. And even if I manually save and restore the URL the user was looking at previously, the scroll position is not restored. Are the docs just wrong?
The docs are right, but very incomplete. Here's what's going on. If a web view participates in state restoration (I'm assuming you know what this means - everything has to have a restorationIdentifier, and so on), and if the web view had a request (not an HTML string) when the user left the app, the web view will automatically return to life containing the same request as its request property, and with its Back and Forward lists intact. Thus, you can use the state restoration mechanism to restore the state of the web view, but you have to perform a little extra dance. This dance is so curious and obscure that initially I was under the impression that a web view's state couldn't really be saved and restored, despite the documentation's assertion that it could.
There are two secrets here; once you know them, you'll understand web view state restoration:
A restored web view will not automatically load its request; that's up to your code.
After a restored web view has loaded its request, the first item in its Back list is the same page in the state the user left it (scroll and zoom).
Knowing this, you can easily devise a strategy for web view state restoration. The first thing is to detect that we are restoring state, and raise a flag that says so:
-(void)decodeRestorableStateWithCoder:(NSCoder *)coder {
[super decodeRestorableStateWithCoder:coder];
self->_didDecode = YES;
}
Now we can detect (perhaps in viewDidAppear:) that we are restoring state, and that the web view magically contains a request, and load that request:
if (self->_didDecode && wv.request)
[wv loadRequest:wv.request];
Now for the tricky part. After the view loads, we immediately "go back." This actually has the effect of restoring the user's previous scroll position (and of removing the extra entry from the top of the Back stack). Then we lower our flag so that we don't make this extra move at any other time:
- (void)webViewDidFinishLoad:(UIWebView *)wv {
if (self->_didDecode && wv.canGoBack)
[wv goBack];
self->_didDecode = NO;
}
The UIWebView is now in the state it was in when the user previously left the app. We have saved and restored state using the built-in iOS 6 state saving and restoration feature.
I have tried Matt's answer and it works well, however if there are 'forward' pages in the history stack-they will be replaced by the restored request within the web view object.
A better approach is to instead call the 'reload' method on the webview object, this will restore the history in both directions as well as the zoom and content scroll offset.
If you'd like an example of my approach or some more functionality for your own webview, take a look at my open source fork of SVWebViewController here.