#actionscript-3 #apache-flex #flex3
#actionscript-3 #apache-flex #flex3
Вопрос:
Если у меня есть файл .mxml, в котором есть метод и общедоступное свойство, могу ли я заставить метод выполняться при изменении свойства?
<?xml version="1.0" encoding="utf-8"?>
<mx:HBox xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
[Bindable]public var myProperty:MyType;
private function myMethod(myProperty):void
{
// Method to run every time myProperty changes
}
]]>
</mx:Script>
</mx:HBox>
В другой файл .mxml я добавил этот файл .mxml следующим образом:
<viewComponents:MyViewComponent myProperty="{myVariable}" />
Ответ №1:
Поскольку об этом еще никто не говорил, я предложу второй подход.
Каждое свойство в платформе Flex Framework будет отправлять свойство с именем что-то вроде *property*Changed. где property — это имя свойства, которое должно быть изменено. Указанные свойства реализованы с использованием методов get set, как упоминали другие. Что-то вроде этого:
private var _myProperty:MyType;
[Bindable(myPropertyChanged)]
public function get myProperty():MyType
{
return _myProperty;
}
public function set myProperty(value:MyType):void
{
_myProperty = value;
dispatchEvent(new Event('myPropertyChanged'));
}
Это имя события, указанное в привязываемых метаданных, используется для целей привязки. Итак, вместо вызова вашего метода внутри набора, вы могли бы прослушать это событие myPropertyChanged:
component.addEventListener('myPropertyChanged',onMyPropertyChanged)
И в других местах кода:
protected function onMyPropertyChanged(event:Event):void{
// do other processing
}
Это может быть излишеством для того, чего вы пытаетесь достичь; или нет. Поскольку вы не вдавались в подробности того, чего вы пытались достичь, я не уверен.
Если ваша новая функциональность каким-либо образом связана с жизненным циклом компонента Flex, например, изменением отображения или размера, вам следует выполнять изменения в ethods жизненного цикла, а не в вашем методе set. Что-то вроде этого:
private var _myProperty:MyType;
private var _myPropertyChanged:Boolean = false
[Bindable('myPropertyChanged')]
public function get myProperty():MyType
{
return _myProperty;
}
public function set myProperty(value:MyType):void
{
_myProperty = value;
_myPropertyChanged = true;
invalidateProperties();
invalidateDisplayList();
invalidateSize()
invalidateSkinState(); // spark comps only
dispatchEvent(new Event('myPropertyChanged'));
}
Методы invalidate принудительно перезапустят метод жизненного цикла компонента во время следующего события визуализации, и вы можете использовать подобный код в соответствующем методе:
if(_myPropertyChanged == true){
_myPropertyChanged = false;
// do other processing
}
Комментарии:
1. Не следует ли поместить название события
[Bindable]
rag в кавычки следующим образом[Bindable("myPropertyChanged")]
?2. И чтобы сообщить true, вам не нужно отправлять событие вручную в вашем случае. Если оставить
[Bindable]
тег в покое без параметров, это автоматически вызовет"propertyChange"
событие (с помощьюmxmlc
компилятора). Но в любом случае есть много случаев, когда ручная отправка событий может быть очень полезной. И, конечно, класс, который отправляет событие вручную, должен быть унаследован отEventDispatcher
или реализоватьIEventDispatcher
.3. @constantiner Внутри платформы Flex события ‘PropertyChange’ отправляются вручную; поэтому я всегда делал это таким образом в моем собственном коде. Я не уверен, что компоненты MXML выполняют другие функции, чем компоненты AS only. Но вы правы, для отправки события класс должен расширить EventDispatcher или реализовать IEventDispatcher. Все компоненты пользовательского интерфейса Flex делают это.
4.
mxmlc
всегда генерирует некоторый код для классов ActionScript с[Bindable]
объявлениями, даже если они не унаследованы отEventDispatcher
. Вы можете увидеть это с помощью-keep-generated-actionscript=true
.
Ответ №2:
Вы можете использовать методы доступа get
и set
. Более подробная информация находится здесь.
В вашем случае это что-то вроде:
private var _myProperty:MyType;
public function set myProperty(value:MyType):void
{
_myProperty = value;
// he best way is to place myMethod body here
myMethod(_myProperty);
}
[Bindable]
public function get myProperty():MyType
{
return _myProperty;
}
Комментарии:
1. @Brian L Я проголосовал за отклонение редактирования. Сделать полный класс привязываемым могло бы сработать, но я бы счел это плохой практикой во многих ситуациях. Многие свойства в любом данном классе, скорее всего, не нужно делать привязываемыми; так зачем добавлять код, чтобы сделать их такими?
2. @www.Flextras.com Это понятно, я полагаю, вы правы. Имеет смысл, что наилучшей практикой было бы отмечать только необходимые поля
[Bindable]
. Тем не менее, я хотел указать запрашивающему (@DaveC) на возможность привязки всего класса.
Ответ №3:
Вот как я бы это сделал. Создайте функцию настройки, которая вызывает предлагаемый вами метод:
var _mystatus:Number = 0;
function set mystatus(val:Number):void
{
_mystatus = val;
alertfunction();
}
function get mystatus():Number
{
return _mystatus;
}