Форум Flasher.ru

Форум Flasher.ru (http://www.flasher.ru/forum/index.php)
-   Flex (http://www.flasher.ru/forum/forumdisplay.php?f=84)
-   -   При добавлении MXML компонента в контейнер, нельзя обратиться к его дочерним объектам (http://www.flasher.ru/forum/showthread.php?t=175610)

Acrossfy 21.02.2012 05:17

При добавлении MXML компонента в контейнер, нельзя обратиться к его дочерним объектам
 
Здравствуйте, есть простенький MXML компонент на основе SkinnableContainer:

Код AS3:

<?xml version="1.0" encoding="utf-8"?>
<s:SkinnableContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
                  xmlns:s="library://ns.adobe.com/flex/spark"
                  styleName="mySkin"
                  addedToStage="init()">
 
        <s:states>
                <s:State name="active"/>
                <s:State name="inactive"/>
        </s:states>
 
        <fx:Script>
                <![CDATA[
                        import spark.components.Button;
 
                        public var selectButton:Button = new Button;
                        public var closeButton:Button = new Button;
 
                        private function init():void
                        {
                                selectButton.styleName = 'SelectButton';
                                closeButton.styleName = 'CloseButton';
                                this.addElement(selectButton);
                                this.addElement(closeButton);
                        }
                ]]>
        </fx:Script>
 
        <!--
        <s:Button id="selectButton" includeIn="active, inactive" styleName="SelectButton" />
        <s:Button id="closeButton" includeIn="active" styleName="CloseButton"/>
        -->
</s:SkinnableContainer>

Как видно, AS3 код добавляет две кнопки. Тоже самое делается ниже через mxml синтаксис(закоментировано). При добавлении этого компонента где-либо в программе, мне нужно тут же обратиться к его дочерним объектам, то бишь кнопкам.
Если использовать mxml синтаксис, то при обращении к кнопке, вылетает ошибка:"Cannot access a property or method of a null object reference". Если использовать AS3, то все работает ок. Вердикт в том, что кнопки, добавленные через mxml синтаксис, не успевают инициализироваться на момент обращения к ним извне.

Проблема заключается в том, что мне нужно в данном компоненте использовать, как раз mxml, поэтому хотелось бы как-то обойти этот нюанс.
Заранее благодарен за любой совет или помощь.

Gaen 21.02.2012 06:24

попробуйте повесить вызов init на creationComplete

Acrossfy 21.02.2012 12:20

Мне не нужен init(). AS3 код вызванный по addedToStage="init()" работает отлично. Но мне нужно избавиться от AS3 в этом компоненте.

Silicium 21.02.2012 12:31

Как у Вас выглядит AS3 код с mxml-компонентами?

Acrossfy 21.02.2012 13:57

Цитата:

Как у Вас выглядит AS3 код с mxml-компонентами?
Не понимаю вашего вопроса. У меня есть простейший компонент на основе контейнера. Есть два способа его реализации.
Первый на MXML:
Код AS3:

<?xml version="1.0" encoding="utf-8"?>
<s:SkinnableContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
                  xmlns:s="library://ns.adobe.com/flex/spark"
                  styleName="mySkin">
 
        <s:Button id="selectButton" styleName="SelectButton" />
        <s:Button id="closeButton" styleName="CloseButton"/>
</s:SkinnableContainer>

Второй на AS3(внутри MXML):
Код AS3:

<?xml version="1.0" encoding="utf-8"?>
<s:SkinnableContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
                  xmlns:s="library://ns.adobe.com/flex/spark"
                  styleName="mySkin"
                  addedToStage="init()">
 
        <fx:Script>
                <![CDATA[
                        import spark.components.Button;
 
                        public var selectButton:Button = new Button;
                        public var closeButton:Button = new Button;
 
                        private function init():void
                        {
                                selectButton.styleName = 'SelectButton';
                                closeButton.styleName = 'CloseButton';
                                this.addElement(selectButton);
                                this.addElement(closeButton);
                        }
                ]]>
        </fx:Script>
</s:SkinnableContainer>

Теперь мне нужно в каком-либо месте моей программы инициализировать этот компонент, например вот так:
Код AS3:

        var myComp:MyComp = new MyComp; //создаю новый экземпляр
        rootContainer.addElement(myComp); //добавляю его в контейнер
 
        myComp.selectButton.label = 'New Button'; //Задаю лейбл для дочерней кнопки в этом копоненте
        myComp.addEventListener(MouseEvents.CLICK, someFunction)//Задаю событие

Так вот. Если мой компонент написан первым способом, возникает ошибка "Cannot access a property or method of a null object reference". Если же вторым, то все работает ОК. Отсюда вывод, что кнопки описанные на MXML дольше инициализируются.
Проблема состоит в том, что нужно использовать только первый способ, то бишь чистый MXML.

Добавлено через 25 минут
Разобрался.
Чтобы дочерний компонент(кнопка в данном случае) инициализировался сразу со своим родителем, нужно добавить ему параметр – itemCreationPolicy="immediate". Тогда эта ошибка не возникает.
То бишь вот так вот:
Код AS3:

<?xml version="1.0" encoding="utf-8"?>
<s:SkinnableContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
                  xmlns:s="library://ns.adobe.com/flex/spark"
                  styleName="mySkin">
 
        <s:Button id="selectButton" styleName="SelectButton" itemCreationPolicy="immediate" />
        <s:Button id="closeButton" styleName="CloseButton" />
</s:SkinnableContainer>


Silicium 21.02.2012 15:03

"инициализировался" и "добавлялся на сцену" - разные вещи.

Acrossfy 21.02.2012 17:56

Цитата:

"инициализировался" и "добавлялся на сцену" - разные вещи.
Во-первых: "Инициализация (от англ. initialization, инициирование) — создание, активация, подготовка к работе, определение параметров."

Во-вторых, в начале топика я весьма четко обрисовал ситуацию:"При добавлении этого компонента где-либо в программе, мне нужно тут же обратиться к его дочерним объектам, то бишь кнопкам."

В-третьих, см. название темы.

saprahan 29.02.2012 14:01

Цитата:

Сообщение от Acrossfy (Сообщение 1064445)
Во-первых: "Инициализация (от англ. initialization, инициирование) — создание, активация, подготовка к работе, определение параметров."

Во-вторых, в начале топика я весьма четко обрисовал ситуацию:"При добавлении этого компонента где-либо в программе, мне нужно тут же обратиться к его дочерним объектам, то бишь кнопкам."

В-третьих, см. название темы.

На creationComplete вешайте подобные действия, а не на инит. Обратите также внимание на то, что у mxml есть default parameter и это не обязательно this

Acrossfy 29.02.2012 14:12

[IMG]http://s017.***********/i405/1112/f5/ca256d857b1c.png[/IMG]

А мне и не нужно ни creationComplete, ни init, ни addedtostage. Мне вообще не нужно запускать что-либо внутри самого моего компонента при его добавлении, в нем вообще не должно быть никакого кода и выше я это популярно объяснил. Мне лишь нужно добавить этот компонент в контейнер в моем главном View, и тут же задать дочерним объектам контейнера определенные параметры из этого самого View, и как я уже написал, решение давно найдено.


Часовой пояс GMT +4, время: 13:49.

Copyright © 1999-2008 Flasher.ru. All rights reserved.
Работает на vBulletin®. Copyright ©2000 - 2026, Jelsoft Enterprises Ltd. Перевод: zCarot
Администрация сайта не несёт ответственности за любую предоставленную посетителями информацию. Подробнее см. Правила.