views:

63

answers:

3

Hi everyone, this is a follow up question from this one, I don't want to keep going in the comments and preventing people from getting hard-earned reputation... :)

In my Cairngorm command class, to get it to compile I needed to tell it what myCanvas was, so I used this line:

var myCanvas : MyCanvas = new MyCanvas;

I'm guessing that's wrong, though, because although it compiles, if I try to do something like this:

if (myCanvas.subObject.value == 0) { ... }

it'll throw this error:

TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at com.foo.bar.command::MyCommand/execute()

as if the subObject doesn't exist. It looks like I might be getting a new instance of MyCanvas, not the instance I want from the main.mxml with an id of myCanvas. Am I right? How do I fix this?

Edit (10:59pm GMT+1): Okay, so it looks like I've been way too vague here. Here's my main.mxml:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
    xmlns:control="com.foo.bar.control.*" 
    xmlns:business="com.foo.bar.business.*"
    xmlns:view="com.foo.bar.view.*"
    applicationComplete="com.foo.bar.util.StartupUtil.init()"
    horizontalScrollPolicy="off"
    verticalScrollPolicy="off"
    borderThickness="0"
    paddingBottom="0"
    paddingLeft="0"
    paddingTop="0"
    paddingRight="0"
>
    <mx:Script>
        <![CDATA[
            import com.foo.bar.model.PlayerModelLocator;

            [Bindable]
            private var model : PlayerModelLocator = PlayerModelLocator.getInstance();
        ]]>
    </mx:Script>

    <!-- ========================================================================== -->

        <!-- the ServiceLocator where we specify the remote services -->
        <business:Services id="services" />

        <!-- the FrontController, containing Commands specific to this application -->
        <control:PlayerController id="controller" />

    <!-- ========================================================================== -->

  <mx:Style source="assets/main.css" />
  <view:MyCanvas id="myCanvas" /> 

</mx:Application>

And here's my com/foo/bar/command/MyCommand.as:

package com.foo.bar.command {
    /* add to controller
    addCommand( MyEvent.EVENT_CHANGE_VOLUME, ChangeVolumeCommand );
    */
    import flash.net.SharedObject;
    import com.adobe.cairngorm.control.CairngormEvent;
    import com.adobe.cairngorm.commands.ICommand;

    import com.foo.bar.model.PlayerModelLocator;
    import com.foo.bar.event.MyEvent;
    import com.foo.bar.view.*;

    public class ChangeVolumeCommand implements ICommand {
        public function execute(event:CairngormEvent):void {
      var model : PlayerModelLocator = PlayerModelLocator.getInstance();
      var myEvent : MyEvent = MyEvent(event);
      var myCanvas : MyCanvas = new MyCanvas();
      var so:SharedObject = SharedObject.getLocal("fixie.video");
      if (myCanvas.subObject.value == 0) {
        trace("subobject value is 0");
      }
        }
    }
}

Basically, I want to get a handle on the object with ID myCanvas in main.mxml using the myCanvas object in MyCommand.as

+1  A: 

What is the scope of your myCanvas variable? Is it inside a method somewhere? You will need to make it public or give it getter/setter to be able to access it.

You may also be trying to reference it before it has been added to its parent, using the addChild() method.

There really isn't enough code in your examples to determine the problem, but these things should give you somewhere to start looking.

Robusto
It's a Cairngorm view defined in MXML, instantiated in main.mxml with `<view:MyCanvas id="myCanvas" />`, where `view` is mapped to `com.foo.bar.view.*`.
Aaron B. Russell
@Aaron B. Russell: Now I'm confused. You do realize that this comment contradicts what you have in your question, right? If you are creating the myCanvas instance in ActionScript, as in your question, you would not have already created it in MXML, and vice versa.
Robusto
Sorry for the confusion, I've gone back and edited the original post now.
Aaron B. Russell
OK, it's pretty clear now that your problem is that you haven't added the myCanvas to the displayList when you are calling the execute method. You should learn about the lifecycle, as Wade Mueller mentions above, especially the protected methods commitProperties, measure, and updateDisplayList.
Robusto
I'll go read up on those things. Thanks for your help. :)
Aaron B. Russell
+2  A: 

Could be a couple of things. First, you need parentheses on your class name after the "new" statement: new MyCanvas(); Second, you may be trying to access your sub component before the component lifecycle is ready for you to do so. (It's hard to tell from the code you posted since there isn't enough context.)

Wade Mueller
Sorry for the confusion, I've gone back and edited the original post now.
Aaron B. Russell
I'm not familiar with cairngorm, but the non-OO (read lame) way to access it would be to reference it like so: FlexGlobals.topLevelApplication.myCanvas.subObject. The question I would have for you is who is sending the event? With regular flex (non-cairngorm) events, you can access the "target" property of the event to get a reference to the sender. If the sender is myCanvas, you could just access the object like so: (target as MyCanvas).subObject. Hope that helps.
Wade Mueller
+1  A: 

1 way is to add eventListener when your myCanvas will be ready after CreationComplete and to do all your stuff

and the second is: define your subObject as in myCanvas class so you'll be able to access it on Init Stage of your component.

regards Eugene

p.s. all of the time everybody want to get answer without well formed sample of their problem, its terrible!!

Eugene
Sorry for the confusion, I've gone back and edited the original post now.
Aaron B. Russell
if you want to handle myCanvas in myCommand, how did you connected them? i don't see it???there are a bad way to use try this:trace(FlexGlobals.topLevelApplication.myCanvas.subObject.toString());
Eugene