PDA

Просмотр полной версии : Доступ к data-provider'у из небазового state


yana_flash
27.12.2006, 14:47
Мне нужно в программе отобразить на экране древовидную структуру. Базовый State у моей программы - форма для логина, а само дерево рисуется в другом State, после успешного входа в систему. Поместить data-provider непосредственно в тот же State, что и дерево, мне не удается:


<mx:states>
<mx:State name="ViewContent"> /* Здесь ошибка */
<mx:XMLList id="treeData">
<node...>
...
</mx:XMLList>
<mx:Tree dataProvider="{treeData}" ... />
</mx:State>
</mx:states>


Этот код выдает ошибку "In initializer for 'overrides': type XMLList is not assignable to target Array element type".
Ага, значит, содержимое State представляется в виде массива операций, необходимых для инициализации состояния и XMLList не может быть таким элементом? Хорошо, вынесем XMLList за рамки State:


<mx:states>
<mx:State name="ViewContent">
<mx:Tree dataProvider="{treeData}" ... />
</mx:State>
</mx:states>

<mx:XMLList id="treeData">
<node...>
...
</mx:XMLList>


На этот раз ошибки нет, но и в дереве нет элементов. Значит, не смогло оно их получить из XMLList'а. Попробовала для проверки вынести дерево из State "в корень" - пусть висит на экране во всех состояниях. Все заработало. Значит, когда дерево создается внутри State, оно почему-то не может обратиться к XMLList treeData по имени. Скорее всего, изменилась область видимости?

Как мне вставить в расположенное в отдельном не-базовом State дерево Tree данные из XMLList'а? Какой идентификатор указать?

yana_flash
28.12.2006, 18:41
Да уж... Сформулировала вопрос так, что сама не понимаю... Попробую по-другому:


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" cornerRadius="10">

<mx:Script><![CDATA[
import flash.display.Sprite;
import flash.events.*;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;

[Bindable]
public var selectedNode:Object;

private function handleLoginEvent():void {
lblInfo.text = "Вход в систему...";
// Отправляем логин и пароль
Application.application.currentState="MyTreeState";
}

// Event handler for the Tree control change event.
public function treeChanged(event:Event):void {
selectedNode=Tree(event.target).selectedItem;
}
]]></mx:Script>

<mx:XMLList id="treeData">
<node label="Mail Box">
<node label="Inbox">
<node label="Marketing"/>
<node label="Product Management"/>
<node label="Personal"/>
</node>
<node label="Outbox">
<node label="Professional"/>
<node label="Personal"/>
</node>
<node label="Spam"/>
<node label="Sent"/>
</node>
</mx:XMLList>

<mx:states>
<mx:State name="MyTreeState">
<mx:RemoveChild target="{txtLogin}"/>
<mx:RemoveChild target="{txtPassword}"/>
<mx:RemoveChild target="{button1}"/>
<mx:RemoveChild target="{label1}"/>
<mx:RemoveChild target="{label2}"/>
<mx:RemoveChild target="{lblInfo}"/>
<mx:RemoveChild target="{myTree2}"/>
<mx:SetStyle target="{panel1}" name="horizontalCenter"/>
<mx:SetStyle target="{panel1}" name="verticalCenter"/>
<mx:SetStyle target="{panel1}" name="left" value="10"/>
<mx:SetStyle target="{panel1}" name="top" value="10"/>
<mx:SetProperty target="{panel1}" name="width" value="711"/>
<mx:SetProperty target="{panel1}" name="height" value="606"/>

<mx:AddChild relativeTo="{panel1}" position="lastChild">
<mx:Label width="100%" color="blue"
text="Select a node in the Tree control."/>

<mx:HDividedBox width="100%" height="100%">
<mx:Tree id="myTree" width="50%" height="100%" labelField="@label"
showRoot="true" dataProvider="{treeData}" change="treeChanged(event)"/>
<mx:TextArea height="100%" width="50%"
text="Selected Item: {selectedNode.@label}"/>
</mx:HDividedBox>
</mx:AddChild>
</mx:State>
</mx:states>

<mx:Panel width="350" height="200" layout="absolute" horizontalAlign="center" verticalAlign="middle" verticalCenter="0" horizontalCenter="0" title="MyTree" id="panel1">
<mx:Label x="45" y="32" text="Имя:" fontWeight="bold" textAlign="left" id="label1"/>
<mx:Label x="24" y="62" text="Пароль:" fontWeight="bold" textAlign="left" id="label2"/>
<mx:TextInput x="85" y="30" id="txtLogin" width="200" cornerRadius="0"/>
<mx:TextInput x="85" y="60" width="200" id="txtPassword" displayAsPassword="true"/>
<mx:Button x="227" y="90" label="Войти" click="handleLoginEvent()" id="button1"/>
<mx:Label x="10" y="114" width="310" height="36" id="lblInfo" textAlign="center" fontWeight="bold"/>
<mx:Tree id="myTree2" width="50%" height="100%" labelField="@label"
showRoot="true" dataProvider="{treeData}" change="treeChanged(event)"/>
</mx:Panel>
</mx:Application>


Вопрос:
почему myTree2 в базовом State прекрасно получает данные из treeData, а точно такое же дерево myTree, создаваемое в MyTreeState, не получает данных из treeData?

Nirth
28.12.2006, 19:18
Вопрос такой, а зачем ты заменяешь Tree, нельзя ли одно и тоже дерево просто увеличить?

yana_flash
29.12.2006, 16:21
Я не заменяла дерево. Просто у меня есть 2 состояния программы. В базовом на экране - логин и пароль (и не должно быть никаких деревьев), а на залогиненном состоянии - появляется дерево. Дерево в базовом состоянии я ввела для того, чтобы убедиться, что не допустила явных ошибок и все вроде бы должно работать. Теперь пытаюсь понять, в чем моя ошибка. Пока - увы, никаких идей...

Nirth
29.12.2006, 17:35
Если честно, очень трудно отследить действия в некомментированном коде, я пытался понять что вы там делаете, и почему столько объектов когда вроде как 2 поля, 1 кнопка, но не врубился.

__i
02.01.2007, 14:46
оставь все как есть но только вынеси дата провайдер дерева из стейта, помести его в "корень" приложения.

Nirth
02.01.2007, 15:03
О стыд мне и позор, не заметил этого.

Кстати в документации настоятельно рекомендуют все не визуальные объекты (модели, коллекции, веб сервисы и тд хранить в корне.

yana_flash
12.01.2007, 11:41
оставь все как есть но только вынеси дата провайдер дерева из стейта, помести его в "корень" приложения.

Полный исходный текст приведен в моем втором сообщении этой темы. Если не ошибаюсь, data provider находится именно в корне, а не внутри блока <mx:states>...</mx:states>. И тем не менее, дерево, созданное в базовом state прекрасно получает данные от провайдера. А дерево, создающееся в state MyTreeState, не получает данных от того же, прописанного в корне, провайдера.

__i
12.01.2007, 13:07
Я даже не поленился и вставил код в билдер.

Диагноз: плохо разобралась в работе <mx:AddChild>

С твоим датапровайдером все нормально, все деревья получают этот хмл нормально, но ты просто не помещаешь в дисплей лист свое дерево (не делаешь HDividedBox"у нормальный аддчаилд) и вообще ничего у тебя не добавляеться (где в панели лейбл где текстовое поле ?).

Чтобы вылечить попробуй "оберни" в отдельный AddChild и лейбл и HDividedBox.

Типа все ;)

yana_flash
12.01.2007, 14:51
Спасибо! Заменила

<mx:AddChild relativeTo="{panel1}" position="lastChild">
<mx:Label width="100%" color="blue"
text="Select a node in the Tree control."/>

<mx:HDividedBox width="100%" height="100%">
<mx:Tree id="myTree" width="50%" height="100%" labelField="@label"
showRoot="true" dataProvider="{treeData}" change="treeChanged(event)"/>
<mx:TextArea height="100%" width="50%"
text="Selected Item: {selectedNode.@label}"/>
</mx:HDividedBox>
</mx:AddChild>


на


<mx:AddChild relativeTo="{panel1}" position="lastChild">
<mx:Label width="100%" color="blue"
text="Select a node in the Tree control."/>
</mx:AddChild>

<mx:AddChild relativeTo="{panel1}" position="lastChild">
<mx:HDividedBox width="100%" height="100%">
<mx:Tree id="myTree" width="50%" height="100%" labelField="@label"
showRoot="true" dataProvider="{treeData}" change="treeChanged(event)"/>
<mx:TextArea height="100%" width="50%"
text="Selected Item: {selectedNode.@label}"/>
</mx:HDividedBox>
</mx:AddChild>


и все заработало!

__i
12.01.2007, 15:06
ну и замечательно :D