Почему моя защищенная от переопределения функция createChildren игнорируется? - PullRequest
1 голос
/ 02 июня 2009

Вот ошибка:

    TypeError: Error #1009: Cannot access a property or method of a null object reference.
        at view::ScoreBoard/setChipCount()[C:\Flex Builder 3\StackOverflowQuestion\src\view\ScoreBoard.as:32]
        at model::MainDeckScoreBoard()[C:\Flex Builder 3\StackOverflowQuestion\src\model\MainDeckScoreBoard.as:21]
        at model::MainDeckScoreBoard$cinit()
        at global$init()[C:\Flex Builder 3\StackOverflowQuestion\src\model\MainDeckScoreBoard.as:5]
        at main()[C:\Flex Builder 3\StackOverflowQuestion\src\main.mxml:13]
        at _main_mx_managers_SystemManager/create()
        at mx.managers::SystemManager/initializeTopLevelWindow()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:3188]
        at mx.managers::SystemManager/<a href="http://www.adobe.com/2006/flex/mx/internal::docFrameHandler()[C" rel="nofollow noreferrer">http://www.adobe.com/2006/flex/mx/internal::docFrameHandler()[C</a>:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:3064]
        at mx.managers::SystemManager/docFrameListener()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\managers\SystemManager.as:2916]

Вот main.mxml:

    <?xml version="1.0"?>
    <mx:Application
        xmlns:mx="http://www.adobe.com/2006/mxml"
        creationComplete="initApp()"
    >
        <mx:Script>
            <![CDATA[
                import model.MainDeckScoreBoard;

                public var _mainDeckScoreBoard:MainDeckScoreBoard = MainDeckScoreBoard.instance;

                private function initApp():void {
                    this.addChild(_mainDeckScoreBoard);
                }
            ]]>
        </mx:Script>
    </mx:Application>

Вот MainDeckScoreBoard.as:

package model {
    import view.ScoreBoard;

    [Bindable]
    public dynamic class MainDeckScoreBoard extends ScoreBoard {

        /** Storage for the singleton instance. */
        private static const _instance:MainDeckScoreBoard = new MainDeckScoreBoard( SingletonLock );

        /** Provides singleton access to the instance. */
        public static function get instance():MainDeckScoreBoard {
            return _instance;
        }

        public function MainDeckScoreBoard( lock:Class ) {
            super();
            // Verify that the lock is the correct class reference.
            if ( lock != SingletonLock ) {
                throw new Error( "Invalid Singleton access.  Use MainDeckScoreBoard.instance." );
            }
            this.setChipCount("0");
        }

    } // end class
} // end package

class SingletonLock {
} // end class

Вот ScoreBoard.as:

package view {
    import mx.containers.HBox;
    import view.ScoreBoardLabel;
    import view.ChipCountContainer;
    import view.CardRankList;

    public dynamic class ScoreBoard extends HBox {

        /** The chip count. */
        public var _chipCount:ChipCountContainer;

        public function ScoreBoard() {

            super();

            this.width = 489;
            this.height = 40;
            this.setStyle("horizontalScrollPolicy", "off");
        }

        override protected function createChildren():void {

            super.createChildren();

            if(!_chipCount) {
                _chipCount = new ChipCountContainer();
                this.addChild(_chipCount);
            }
        }

        public function setChipCount(labelText:String):void {
            _chipCount._chipCountLabel.text = labelText;
            invalidateDisplayList();
        }
    }
}

Вот ChipCountContainer.as:

package view {
    import mx.containers.Canvas;

    public dynamic class ChipCountContainer extends Canvas {

        /** The label. */
        public var _chipCountLabel:ChipCountLabel;

        public function ChipCountContainer() {

            super();

            this.width = 20;
            this.height = 20;
        }

        override protected function createChildren():void {

            super.createChildren();

            if(!_chipCountLabel) {
                _chipCountLabel = new ChipCountLabel();
                this.addChild(_chipCountLabel);
            }
        }
    }
}

Я методично передвигал вещи и махал недействительными благовониями из Списка отображения во время исполнения детского танца, но мне удалось только полностью запутаться. Я искал в библиотеках Flex аналогичные конструкции, и для меня это выглядит нормально, но, похоже, я просто не понимаю эту концепцию.

1 Ответ

2 голосов
/ 02 июня 2009

Я думаю, что вы путаете порядок создания экземпляров. А именно, если вы хотите использовать setChipCount после того, как дочерние компоненты компонента были инициализированы, вам следует дождаться, чтобы сработало событие инициализации, т.е.

    public dynamic class MainDeckScoreBoard extends ScoreBoard {

    ...

        public function MainDeckScoreBoard( lock:Class ) {
            super();
            // Verify that the lock is the correct class reference.
            if ( lock != SingletonLock ) {
                throw new Error( "Invalid Singleton access.  Use MainDeckScoreBoard.instance." );
            }

            // wait for the children to be created
            addEventListener(FlexEvent.INITIALIZE, onInitialize);
        }

        // executes when the children of this component have been created
        private function onInitialize(event:FlexEvent):void {
            this.setChipCount("0");
        }

    } // end class

Для более подробного объяснения жизненного цикла создания компонента этот документ может быть полезен:

http://livedocs.adobe.com/flex/3/html/help.html?content=components_06.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...