I have an application where you arrive at a photo album listing via various means (searching, drill down by category, etc). From the album, you click open individual photos and iterate through them using left/right arrows, as well as various editing tools. Each of the iterate/tool actions does a history.push() to add the route to the router history. I am trying to implement a button that will go back to the exact place in the history before you started viewing individual photos. To do that, I'd like to walk the history stack backwards to the point where the the history matches 1 of several patterns then do a history.go(-14) (or whatever) to jump back to the route that started the whole chain.
I've been searching the React router code as well as the HTML5 History object and I don't see any way of accessing the history stack directly so I can walk it back. I'd rather not depend on making each individual photo action push their path to a separate place since that makes it fragile (each photo action is built by a different developer and adding new actions in the future will require previous knowledge to remember to do that).
I can't go to a hard coded path because that would be pushed to the top of the history stack and hitting back arrow would just return you to the last individual photo page instead of the search page that generated the album list in the first place.
Any suggestions on accessing the history stack?
I do not know if this would be relevant to your case anymore since this is an old question, but I will put this answer here since I had to solve a similar problem myself.
In my own research, I was not able to find a "history.stack" object, but there is a workaround that is also listed here. Basically, you set up a goBack counter that gets passed to the next route as location state. You can then go back the in the stack however many times the counter says to.
let goBack
if (history.location.state) {
goBack = history.location.state.goBack
} else {
goBack = -1
}
You can pass location state in React Links by replacing the to= prop with an object.
<Link to={
{ pathname: "/next/path", state: { goBack: goBack - 1 } }
}> Click Here! </Link>
You then just call history.go(history.location.state.goBack) whenever you need to go to the entry route.
If you have the possibility of entering one of the changed routes without hitting the entry one (like a user copies and pastes a URL pointing to a single image), then you can add default behaviour.
if (history.location.state) {
history.go(history.location.state.goBack)
} else {
// You can add a default action if a user lands on route from an external link
history.push('/base/url')
}
This solution could also work if you need more complex behaviours like having 'checkpoint' routes that skip any routes in between as you go back. Just change goBack to be a list of numbers (representing the gaps in between each go-back jump) that you can pop each time you revert back to a checkpoint.
Another solution that might tickle your fancy is to just replace the route instead of pushing it to the stack, but this requires writing a custom component that wraps Link. You can find how to do that here
Related
I'm currently working on a UI based game where you have a "world map" containing a grid with zones (squares).
The zones are loaded through a json file coming from a database (MySQL) and are presented in a Grid Layout Group. Each zone has a zoneID in the database which is set in a local variable on the zone prefab.
When the player (you) are clicking on a zone, you will get a "Travel to"-button.
When the "Travel to" button is pressed, the idea is to "move" the player to that zone, coloring the image frame of the zone in yellow to highlight where you are. There is no actual player moving around, just UI and Text displaying the information.
My problem(s):
What would be a good and simple way to let the system know in which zone you are?
I'm thinking about a bool or something like (bool playerInZone), but how do I set it to true/false on other zones?
How do I reset the color when player leaves a zone and enters another? Currently I have no problem setting the color when pressing the button, but I can't seem to figure out how to reset the previous zone.
I can't seem to wrap my head around this...
I'm not sure if code is needed, I just need tips for how to think in this case.
Edit after understanding the question better:
I think I understand where your confusion comes from. You probably think that game-objects should manifest in the game view/physics in some way, where in fact many game-objects are just invisible units carrying game-logic related code.
I think a good solution would be to keep a manager game object that keeps track on the current location of the player. When you intercept a UI input that moves the player you'll do it through the manager, and the manager will be responsible to remove the highlighting from the current zone and apply it to the new zone.
It's probably a good idea to keep the "zones" as child objects of the said manager. Read about how to find game objects from parent game objects. I'm not sure which object intercepts the mouse click, but assuming that it's the zones themselves, than the manager can subscribe to events on the zones that will fire upon being clicked, or simply refactor to have a single object (perhaps the manager) handle the UI inputs.
Hope this is more helpful. Let me know if you need any clarification.
Previous comment
Use a collider trigger.
You can use the OnTriggerEnter and OnTriggerExit to set a bool whenever the player is in the zone. If you want coordination between different triggers and different zones you'll need a manager of some sort to handle this.
From the documentation, it says I can have a collaborative list which contains other collaborative objects, namely another collaborative list. Therefore in my "onFileLoaded" event, I have the following code:
var myRoot = doc.getModel().getRoot().get('myList');
var newList = doc.getModel().createList();
newList.push('Level2');
myRoot.push(newList);
I understand that everytime I reload the file, a new list will be added to "myList". Everything works fine except when I reload the document, that's when the API will only give me "myList" and the "newList" is gone and disappeared into thin air. If I add a string or any other data, the data will persist when I reload the document, but not adding another list to the current list. What am I doing wrong? Thanks in advance.
I am not sure why the above does not work for me, but when I moved the list adding codes out of "onFileLoaded", specifically, adding list to lists only when I click on some DOM element, everything works fine. I supposed these codes should be out of "onFileLoaded" anyways, so it's all good and hopefully someone find these useful.
I have a menu with five buttons. Menu is visible all the time. there is click event for each menu item. which slides corresponding movie clip from left to right. each movie clip has different nature events and respective animation and activity. for example tab 1 brings the video page. and within that movie clip I have video events like play pause volume and on complete etc. events and code. tab 2 has button group for Time and another button group Features. depending on user selection code will calculate and show value on a animated counter. tab 3 has button group for Time and button group Source. as per the user selection it will calculate and show the values as animated graph. and so on.
Right now I have all the individual tab movie clip has its own time line code for its own events. and some crossover variables and references with other tabs. Everything is working as expected. No problem. I know time line code is not the best way to do any complex project.
So, I would like to get the entire coding as one class or more classes if that is the correct way.
I am beginner as far as class logic. I have already created Main as document class and could control the general navigation of tabs and their initial look. But stuck at tab specific button events and other such unique events for the specific tab.
Any help is greatly appreciated. Thanks in advance.
any similar example or suggestions.
First of all, thanks a lot for a prompt response. It seems like I am not even a beginner. I need to read a lot and probalbly grasp all fundamental concepts thoroughly. I have gone through both the links suggested in your comments. I am trying to digest the stuff slowly. I do not have any formal informal education regarding OOP or any sort of programming. To be honest, I have hard time understanding the code you have suggeted. Not because of your code but because of my level of caliber. I will have to spend some time to make myself clearer regarding events and sequence etc. different tab contents are as movieclips to main timeline and already placed on stage. It comes and goes to its corresponding tab button click event. I am not marking your answer as yes because I still need to my own homework based on your suggestion. Thanks a lot once again. I am sure I will ask few more questions later.
This is how I would design it:
I'd have a Menu Class, which only contains the buttons and "converts" clicks on them into more specific events. That might look something like this:
public Class Menu extends Sprite {
protected var buttons:Vector. = new Vector.();
public function Menu() {
super();
var loops:int = numChildren;
for (var i:int=0; i<loops; i++) {
var button:SimpleButton = getChildAt(i) as SimpleButton;
if (button) {
buttons[buttons.length] = button;
button.addEventListener(MouseEvent.CLICK, broadcastMenuEvent);
}
}
}
public function broadcastMenuEvent(e:Event):void {
var button:DisplayObject = e.currentTarget as DisplayObject;
dispatchEvent(new Event(button.name, true));//bubbling, can catch at any level
}
}
The way this is built, you can change the events that are being dispatched simply by changing the name you give the instance of the button on stage. Note that you need to apply Menu as the Base Class and not the Class for this to work if you have "declare instances automatically" unchecked, because doing it that way allows the compiler to generate those instance names for you in a way your base Class doesn't have to know about.
At this point, you can then deal with those events in another place--whether it's your main document Class or whether you have a separate Controller.
I would define each of the Views you described as a separate Class as well. If you have objects coming and going on the stage, you can use one of the techniques described here to handle that. Otherwise, it's fairly straightforward to address your timeline instances from the base Class instead of timeline code. Again, you can listen for those events in the main document Class or a dedicated Controller--the main point is to make sure your Views are not making any important decisions and usually they should not be editing data.
You can choose to have your Main Document orchestrate how the tabs get added and removed (I'm a big fan of using the timeline with goToAndStop, but not everyone shares this preference), or, again, you can separate this logic out to a dedicated Controller. I would suggest that if it's possible to generalize how your Views work to have them implement a single Interface. That way, you can give them a single instance name and manage them all with the same getter/setter pair (assuming you go the timeline route).
Note the Flash compiler isn't terribly sophisticated in this regard, so if you do this and your Views extend different parent Classes, you'll get compiler warnings. Just ignore these--they don't mean anything.
The thing you shoud try to root out of your code completely is the part where Views are referencing each other. The only time it's acceptable for one View to know about another is when it's a parent knowing about its child. Even then, try to have as little specific knowledge as possible. Notice in the Menu View I wrote as an example, the parent only knows there may be some SimpleButtons, but it has no specific knowledge of where they are on stage, what, specifically, is in them, or even what there instance names are.
Instead of having your Views know about one another, have a third party (which, again, you can choose to use the main Document Class for or not) that transfers requests for state changes (in the form of events) from one to another.
I am developing an Windows Forms application using VB.NET that offers the user to lookup addresses on Google Maps through a Web Browser. I can also successfully show the directions between two points to the user, as well as allow the user to drag the route as he/she pleases. My question now is - is it possible for me to get the lattitude/longitude information of the route, i.e. the overview_polyline array of encoded lattitude/longitude points and save it to e.g. a text file on my computer? Or is it possible to get a list of all the addresses located both sides of the route over the entire length of the route, and then save the data to a file on my computer? I'm using HTML files to access and display the Google Maps data in the Web Browser item.
Thank you
This is actually pretty simple if your just looking for the screen coordinates.
// this probably should be in your form initialization
this.MouseClick += new MouseEventHandler(MouseClickEvent);
void MouseClickEvent(object sender, MouseEventArgs e)
{
// do whatever you need with e.Location
}
if your strictly looking for the point in the browser, you need to consider the functions
browser.PointToClient();
browser.PointToScreen();
So, this method is usable if you know exactly where your form is (easy to get its coords) and where you webbrowser control is (easy to get coords of this as well since it's just a control in your form) and then, as long as you know how many pixels from the left or right, and from the top or bottom the image will be displayed, once you get the global mouse click coords (which is easy) you can predict where it was clicked on the image.
Alternatively, there are some scarier or uglier ways to do it here...
You can use the ObjectForScripting property to embed code to do this in the webbrowser. It's ugly to say the least. MSDN has some documentation on the process here: http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.objectforscripting.aspx
Because its really ugly, maybe a better solution is to use AxWebBrowser - it's ugly too but not so scary.
In addition, I found this post of someone wanting to do it on a pdf document, and a MSFT person saying its not possible, but really what he is trying to say is that it isn't built in, even with a pdf document its still possible to predict with high to certain accuracy where it was clicked if you use the first method i described. Here is the post anyway: http://social.msdn.microsoft.com/Forums/en/csharpgeneral/thread/2c41b74a-d140-4533-9009-9fcb382dcb60
However, it is possible, and there are a few ways to do it, so don't get scared from that last link I gave ya.
Also, this post may help if you want to do it in javascript:
http://www.devx.com/tips/Tip/29285
Basically, you can add an attribute on the image through methods available in the webbrowser control, you can add something like onclick="GetCoords();" so when it is clicked, the JavaScript function will get the coords, and then you can use javascript to place the values in a hidden input field (input type="hidden") which you can add through the webbrowser control, or if there is one already on the page, you can use that. So, once you place the coords using javacript into that input field, you can easily grab the value in that using the webbrowser control, eg:
webbrowser1.document.getElementById("myHiddenInputField").value
That will get the value in that field, which you've set through JavaScript. Also, the "GetCoords()" function i mentioned is called SetValues() in the javascript method link i provided above (in the devx.com site) but I named it GetCoords because it makes more sense and didn't want to confuse you with the actual name they used, you can change this to any name you want of course. Here is the javascript they were using, this only gets the coords into a variable, doesn't put it into a hidden input field, we will need to do that in addition (at the end of the javascript SetValues/GetCoords function).
function SetValues()
{
var s = 'X=' + window.event.clientX + ' Y=' + window.event.clientY ;
document.getElementById('divCoord').innerText = s;
}
These guys are just saving it inside a div element, which is visible to users, but you can make the div invisible if you want to use a div field, there is no advantage or disadvantage in doing that, you would just need to set the visible property to false using javascript or css, but still, it is easier to use a hidden input field so you don't need to mess with any of that.
Let me know how you get along.
I would like to re-use a Request.JSON object, but I am not sure how. I'm looking for something like the following example:
// In initialize/constructor
this.request = new Request.JSON( {
method : 'get'
});
// Elsewhere
this.request.setOptions({
url : 'http://...',
onSuccess : onSuccess,
onFailure : onFailure
}).send();
there are going to be certain issues with this kind of approach.
if you only have the one instance handling all requests, then you need to make sure whilst a request is taking place, there is nothing else that can restart it with the new options as its asynchronous. additionally, events will stack up. every new instance that you run will addEvent onComplete/onSuccess/onFailure and they won't always be relevant. so you need to apply removeEvents() to the request instance before each run.
have a look here http://www.jsfiddle.net/dimitar/8a7LG/4/
i am not showing this as an example of how i'd write it but to see the problems that come with it. click the second link first then the first one (jsfiddle adds 2 seconds network lag) and you will see the alert from the second link's onComplete event stacked up on the first one as well. further more, for each click on link 2 you will see a new alert in addition to the old ones.
you must also consider how applicable it is to extend Request.JSON instead but it all depends on your needs.
p.s. if you go over to Request.JSONP this kind of structure may play some tricks, in particular with the callback functions being reset etc.
best of luck :)
edit here's the thing working with removeEvents so you don't get the stacking up: http://www.jsfiddle.net/dimitar/8a7LG/5/
I don't differ with the accepted answer's point, but it actually sidesteps the question IMHO.
Take a look at the following blog post (it's not mine); there, under the subtitle Multiple Links with Request.HTML you can find some guidance about how to reuse the Request instance.
http://ryanflorence.com/basic-ajax-and-json-requests-with-mootools/