Why get singleton DisplayObject Class stage is null?

yellow.as's Avatar

yellow.as

03 Aug, 2014 09:03 AM

I use `injector.map(StageLoadingBar).asSingleton();` to create a singleton class.
when i try to use it , I can not get the stage.

`[Inject]`
`public var loadingBar:StageLoadingBar;`

some where i use:
`trace(loadingBar.stage)` is null

but I put the same class to stage init class
`static public var stageLoadingBar:StageLoadingBar;`

and in StageLoadingBar
`MyProject.stageLoadingBar = this;`

then I trace these at same place:
`trace(loadingBar.stage)` //null
`trace(MyProject.stageLoadingBar)` // [object Stage]

crazy

  1. Support Staff 1 Posted by Ondina D.F. on 04 Aug, 2014 10:08 AM

    Ondina D.F.'s Avatar

    Hello,

    • Firstly, let's recapitulate a few things about Stage.

    "The Stage class represents the main drawing area.

    The Stage object is not globally accessible. You need to access it through the stage property of a DisplayObject instance."

    "When you instantiate a display object, it will not appear on-screen (on the Stage) until you add the display object instance to a display object container that is on the display list.

    When you add any visual element to the Stage, that element becomes a child of the Stage object." [Adobe]

    http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b...

    There is only ONE Stage! The Stage is the base container of display objects. Each application has one Stage object, which contains all on-screen display objects. The Stage is the top-level container and is at the top of the display list hierarchy

    If a display object is not yet on Stage, as a direct child of the Stage or of another display object container, its stage property is null.

    var someView:SomeView = new SomeView();
    Right now, someView.stage is null.

    After adding someView to the display list like this:
    parentDisplayObject.addChild(someView); or like this: parentDisplayObject.addElement (someView);

    someView.stage is [object Stage], which is shared by all display objects in the display list.

    • Secondly, the issue you're encountering is due to the fact that when you inject a view into its mediator and into other classes as well, the injected objects (views) are not the same. The view injected into its mapped mediator is the view that has been added to the stage, where as the view injected into other classes is (probably) not the same as the one on the stage. I'll give an example to make it more clear.
      You should try out the following code, to see what's going on.

    Say, you've mapped SomeView like this:

    injector.map(SomeView).asSingleton();
    
    viewProcessorMap.map(ParentMediator).toInjection();
            
    viewProcessorMap.map(SomeView).toProcess(new MediatorCreator(SomeMediator));
    

    ParentView adds SomeView either through mxml or script:

    var someView:SomeView = new SomeView();
    addElement(someView);
    

    In SomeMediator someView will have a stage property:

    [Inject]
    public var view:SomeView;
    
    override public function initialize():void
    {
        trace("view: "+view+" view.stage "+view.stage);// [object Stage]
    }
    

    In ParenMediator:

    [Inject]
    public var someView:SomeView;
    
    [Inject]
    public var view:ParentView;
    
    override public function initialize():void
    {
        trace("someView: "+ someView +" someView.stage "+ someView.stage);//null
    }
    

    someView's stage will be null in ParenMediator! If you look at the traces, you'll see that someView inside ParentMediator is not the same as the one in SomeMediator. SomeView inside SomeMediator has been already added to the stage, thus it has a stage property. Since SomeView inside ParentMediator is not the same instance as SomeView in SomeMediator and because it hasn't been added to the stage, its stage is null.

    However, you can try this:

    //var someView:SomeView = new SomeView();
    //injector.map(SomeView).toValue(someView);
    
    injector.map(SomeView).asSingleton();
                
    viewProcessorMap.map(ParenMediator).toInjection();      
    viewProcessorMap.map(SomeView).toProcess(new MediatorCreator(SomeMediator));
    

    Then in ParentMediator you add someView to parentView:

    view.addElement(someView);

    Or, better, use ParentView's API to pass someView, and let ParentView add SomeView to its stage:

    view.parentViewMethod(someView);

    After that, both ParentMediator and SomeMediator will have access to SomeView, and someView will have a stage property.

    But, you have to know that ParentMediator will keep a reference to SomeView, so SomeView won't get garbage collected after removing it from stage. Just saying, in case you run into gc issues:)

    Hope that helped.

    Ondina

  2. Support Staff 2 Posted by Ondina D.F. on 01 Sep, 2014 12:31 PM

    Ondina D.F.'s Avatar

    Closing this thread for now. You can re-open it at any time, if need be.

  3. Ondina D.F. closed this discussion on 01 Sep, 2014 12:31 PM.

Comments are currently closed for this discussion. You can start a new one.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac