Reputation: 337
I'm learning flex/flash and I'm lost on this one. I have used the "data" in a bunch of views and it works fine. For some reason it isn't working here.
I set a field to a string here:
function LoginLoaded (e:Event):void {
trace(e.target.data);
var ServerReturn:String;
ServerReturn = new String(e.target.data);
data.UserCommonReturnData = ServerReturn;
navigator.pushView(CommonPlaces, data);
}
and here in the common places view I try to load it back:
var CommonPlacesData:String = new String();
var CurrentSelect:String = new String();
CommonPlacesData = new String(data.UserCommonReturnData);
This gives the error "Access of undefined property data" I don't get it because calling on something like data.PickUpTime (also a string) works fine in other views.
The data begins in the first view like this:
[Bindable] public var User:ObjectProxy = new ObjectProxy();
User.ID = "2314084";
navigator.pushView(TaxiNowOrLaterView, User);
then in later views I call on it like this: (works fine)
var PickUpString:String = new String(data.ID);
Any help would be great!! Thanks!!!
Upvotes: 0
Views: 877
Reputation:
There are few things about your code. First, you really should make it a habit to name the identifiers as appropriate to the language. Identifiers that start with the capital letter and subsequently use minuscule letters for the rest of the logical part of the word (system alternatively known as PascalCase) is employed to only name classes. The rest of identifiers should use camelCase (similar to PascalCase, but the first letter isn't capitalized)**. This greatly reduces the effort at understanding your code. A seasoned AS3 programmer would interpret your code as follows:
// Static constant (!) ID of the class User is assigned (?) a value of "2314084"
User.ID = "2314084";
// invoke a method pushView of a local variable navigator with arguments
// of which first is the class TaxiNowOrLater, the second is the class User
navigator.pushView(TaxiNowOrLaterView, User);
while, perhaps, you didn't mean it.
new String();
In the context of AS3 makes no sense at all. Strings are never references, are immutable and have literal syntax the majority of programmers agreed upon. The code above is identical to ""
. In the similar way, new String(anotherString)
has exact same effect as anotherString
.
Your question: event.target
may be many different things, some of them may have property called "data" and some may not. The general approach to this problem is that you need to cast the value of event.currentTarget
or event.target
to the type you expect to dispatch the event. Suppose you are expecting an event from an instance of a Button
class, then:
private function clickHandler(event:MouseEvent):void {
if (Button(event.currentTarget).enabled) // do things
}
This will not protect you from an error, if the same event was dispatched by an object, which is not a button, but will make the error reporting more conscious, because it would tell you what class was it trying to cast to what other class, when it failed.
If your program logic requires that the handler be aware of events it shouldn't handle (why?) you could then write it like this:
private function clickHandler(event:MouseEvent):void {
var button:Button = event.currentTarget as Button;
if (button && button.enabled) // do things
}
event.target
vs event.currentTarget
- very-very rarely you would need the event.target
, most of the time you need the currentTarget
. I'm not saying it is wrong, but, it looks like it might be the problem. target
is the object that was the first cause of the event. Events may bubble, which means they may travel the display list hierarchy up and down, first from the parent to child, then in reverse direction. In the example below, suppose there was a label on the button, which was clicked once the event was generated - in such case, even if you added a listener to the button, event.target
would be the button label, not the button. currentTarget
is, on the contrary, the immediate object which dispatched the event into the handler.
Few more things: ObjectProxy
is an idiotic class, you probably shouldn't use at any event. It serves no purpose and, perhaps, buggy, but very few cared to discover its bugs so far. In a nutshell, what it does is as follows: it creates an object, which "watches" dynamic creation, assignment and removal of its properties and dispatches events when these events happen. This behavior is prone to a lot of errors and implicit bugs. For example, is foo.bar = "baz"; foo.bar = "baz";
a reassignment of the same property or not? Is foo.bar.baz = "fizzbuzz";
a modification of foo.bar
? What if property name is not a sting? And so on.
Why you shouldn't use it: there is always a better way to treat your data. A more transparent, easier to debug, more efficient. This class is a prototype, which had never really worked. Besides having the behavior described above, it is huge in terms of lines of code that were used to write it. Debugging the errors that happen inside of it requires a lot of time and patience, which are certainly not worth it.
If you need an object to represent a user, define a class, with properties you expect the user to have and just use that class - this will make debugging and understanding your code much easier.
[Bindable]
metadata is evil. I can't tell you you should avoid it, because it is used too often, but, I will. You should avoid it as much as possible. I didn't yet encounter an instance of when the use of this meta would be justified. Much in the similar spirit as ObjectProxy
it is a prototype, something designed for lazy programmers w/o much consideration for either performance or corner cases. This is, again, a source of a lot of implicit bugs, typically difficult to spot due to the code generated around this meta "swallowing" the errors. The alternative to this meta is plain addEventListener(...)
code with custom events.
Unfortunately, a lot of tutorial will use this kind of code to have you quickly started with the language + framework...
** there are some exceptions to this rule: constants are all upper-case and namespace names use underscores to separate the logical part of the word, but never use uppercase letters.
Upvotes: 1