Доступ к элементам, определенным в MXML, из внешней AS
-
06-09-2019 - |
Вопрос
У меня есть MXML с формой и внутри него два TextInput.Я ненавижу наличие каких-либо фрагментов кода внутри файла MXML (я пришел из JavaScript), поэтому я использую
mx:Script source="external.as"
тег для включения любого кода, используемого в любом файле MXML.Проблема в том, что если у меня есть этот код на external.as
файл:
private function populateFromForm():void{
var vo:ValidObject= new ValidObject();
vo.market = marketInput.text;
vo.segment = segmentInput.text;
vo.priceLow = priceLowInput.text;
vo.priceHigh = priceHighInput.text;
}
Где marketInput, сегментInput, PriceLowInput и PriceHighInput — это TextInputs, определенные в файле MXML.Когда я пытаюсь скомпилировать, я получаю 1120:Доступ к неопределенному свойству XXXXX
Я попытался добавить эти строки перед функцией:
public var marketInput:TextInput;
public var segmentInput:TextInput;
public var priceLowInput:TextInput;
public var priceHighInput:TextInput;
Но вместо этого я получаю 1151: Существует конфликт с определением XXXX во внутреннем пространстве имен. что имеет смысл.
Есть ли способ сделать это без необходимости передавать все входные ссылки на функцию в качестве ее параметров?
Решение
Выполнение «кода программной части» во Flex является болезненным.Здесь нет концепции частичных классов или гибкости прототипного наследования, как в Javascript.Google для «гибкого кода» для многих ресурсов.
Я думаю, вам лучше привыкнуть к идее встраивания кода в mxml.Используйте теги скриптов, насколько это возможно, избегая встроенного кода.Если вам приходится писать много кода в MXML, возможно, вы захотите разбить код на несколько пользовательских компонентов.Бонусные баллы, если они многоразовые.
Другие советы
Вам необходимо создать ссылку на экземпляр родительского контейнера TextInputs, а затем использовать эту ссылку для доступа к TextInputs и их свойствам.Я думаю, нам нужны некоторые разъяснения по поводу вашей файловой структуры.Как вы создаете экземпляр родительского контейнера?Я думаю, это то, что вам нужно сделать:
МояФорма.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:TextInput id="marketInput" />
<mx:TextInput id="segmentInput" />
<mx:TextInput id="priceLowInput" />
<mx:TextInput id="priceHighInput" />
</mx:VBox>
SaveVOContainer.as:
package
{
public class SaveVoContainer extends Container
{
private var myForm:MyForm = new MyForm();
public function SaveVOContainer
{
this.addChild(myForm);
}
private function populateFromForm():void{
var vo:ValidObject= new ValidObject();
vo.market = myForm.marketInput.text;
vo.segment = myForm.segmentInput.text;
vo.priceLow = myForm.priceLowInput.text;
vo.priceHigh = myForm.priceHighInput.text;
}
}
}
Канонический способ реализации кода программной части во Flex — через наследование.Вот хорошее объяснение из документов: http://learn.adobe.com/wiki/display/Flex/Code+Behind.В двух словах:
- Объявите класс ActionScript, который будет использоваться в качестве базового класса.
- Установите базовый класс в качестве корневого контейнера в файле MXML.
- Для любых элементов управления, объявленных в вашем файле MXML, вам необходимо переобъявить их как общедоступные члены базового класса, используя то же самое имя (точно так же, как вы делаете выше для вашего блока сценария с исходным тегом, только это работает :-)
Итак, ваш файл ActionScript:
package mypackage
{
import mx.controls.TextInput;
public class myClass extends WindowedApplication
{
public var marketInput:TextInput;
private function populateFromForm():void{
/* As above */
}
}
}
И соответствующий файл MXML:
<?xml version="1.0" encoding="utf-8"?>
<custom:myClass xmlns:custom="mypackage.*"
xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<mx:TextInput id="marketInput"/>
</custom:myClass>
И так далее для других элементов управления TextInput.И теперь ваша функция populateFromForm должна работать.
Это отчасти отвратительно - дважды объявлять одни и те же объекты дважды, но это не совсем тот вред, который описал предыдущий респондент (хотя, возможно, это изменилось во Flex 4, чтобы сделать это менее болезненным, чем было).
импортируйте это в .AS:
import mx.core.Application;
в .AS используйте это:
mx.core.Application.application.component.property = value;
mx.core.Application.application.myText.text = 'test';
есть ли в вашем файле mxml тег сценария, указывающий на ваш файл ActionScript?
<mx:Script source='includes/foo.as' />