Подтвердить что ты не робот

Flex Предупреждение: невозможно привязать свойство foo к классу "Object" (класс не является IEventDispatcher)

У меня есть объект, содержащий десяток или около того полей, которые я хочу связать, чтобы сформировать элементы, чтобы я мог использовать этот объект для отправки данных обратно на сервер, который будет сохранен.

Определение моего объекта-контейнера:

private static const emptyLink:Object = {
    id: -1, title:'',
    trigger1:'',trigger2:'',trigger3:'',trigger4:'',trigger5:'',
    linkTitle:'', linkBody:'',
    answer1:'',answer2:'',answer3:'',answer4:'',answer5:''
};

[Bindable] public var currentLink:Object = emptyLink;

currentLink назначается во время выполнения определенному индексу из ArrayCollection, я просто использую объект emptyLink для целей инициализации, в основном.

<mx:Panel id="triggerPanel" title="Trigger" width="33%">
    <mx:VBox id="tpBoxes" width="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
        <mx:TextInput id="trigger1" width="100%" textAlign="left" text="{currentLink.trigger1}" />
        <mx:TextInput id="trigger2" width="100%" textAlign="left" text="{currentLink.trigger2}" />
        <mx:TextInput id="trigger3" width="100%" textAlign="left" text="{currentLink.trigger3}" />
        <mx:TextInput id="trigger4" width="100%" textAlign="left" text="{currentLink.trigger4}" />
        <mx:TextInput id="trigger5" width="100%" textAlign="left" text="{currentLink.trigger5}" />
    </mx:VBox>
</mx:Panel>

Конечно, это компилируется и отображается просто отлично, но для каждого экземпляра есть предупреждения:

предупреждение: невозможно привязать свойство "trigger1" к классу "Object" (класс не является IEventDispatcher) предупреждение: невозможно привязать свойство "trigger2" к классу "Object" (класс не является IEventDispatcher) предупреждение: невозможно связать свойство "trigger3" с классом "Object" (класс не является IEventDispatcher) предупреждение: невозможно связать свойство "trigger4" с классом "Object" (класс не является IEventDispatcher) предупреждение: невозможно связать свойство "trigger5" с классом "Object" (класс не является IEventDispatcher)

И объект currentLink не обновляется при изменении полей TextInput.

Очевидным ответом является то, что мой объект должен быть экземпляром класса, который реализует IEventDispatcher. Этот ответ не говорит мне об особенностях реализации этого интерфейса (что нужно, а что нет?), И если есть более простой способ сделать это - как встроенный класс, который с радостью примет мои пользовательские свойства и позволит для привязки, без необходимости беспокоиться о деталях реализации интерфейса.

Существует ли такой класс? Если нет, то какой минимальный и/или принятый стандарт для выполнения этой задачи?

4b9b3361

Ответ 1

Вам нужно использовать ObjectProxy (как упоминает Четан), но вам также нужно использовать valueCommit, чтобы получить текст, который вы вводите во входной BACK в свой объект:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
    <mx:Script>
        <![CDATA[
            import mx.utils.ObjectProxy;
              private static const emptyLink:Object = {
    id: -1, title:'',
    trigger1:'',trigger2:'',trigger3:'',trigger4:'',trigger5:'',
    linkTitle:'', linkBody:'',
    answer1:'',answer2:'',answer3:'',answer4:'',answer5:''
};

[Bindable] public var currentLink:ObjectProxy = new ObjectProxy(emptyLink);


private function handleClick():void
{
    trace(currentLink.trigger1);
}
]]>
</mx:Script>

<mx:Panel id="triggerPanel" title="Trigger" width="33%">
        <mx:VBox id="tpBoxes" width="100%" paddingBottom="5" paddingLeft="5" paddingRight="5" paddingTop="5">
                <mx:TextInput  id="trigger1" width="100%" textAlign="left" text="{currentLink.trigger1}" valueCommit="{currentLink.trigger1 = trigger1.text;}"/>

                <mx:Button label="Click" click="handleClick()"/>
        </mx:VBox>
</mx:Panel>        

</mx:WindowedApplication>

Ответ 2

Object не отправляет события. Хотя вы сделали переменную Bindable, свойства объекта, на которые ссылается переменная currentLink, не могут быть связаны.

Используйте ObjectProxy вместо этого.

[Bindable] public var currentLink:ObjectProxy = new ObjectProxy(emptyLink);

Ответ 3

Первое, что вам нужно знать, это то, что привязка в Flex 3 не является двунаправленной. Выражение связывания гарантирует, что если источник выражения привязки (currentLink.trigger1) изменит, что целевой (TextInput) получит уведомление об изменении и обновлении соответственно. Если вы хотите, чтобы привязка проходила в другом направлении, есть как минимум два способа сделать это:

  • Используйте тег mx: Binding, чтобы перенаправить TextInput.text обратно на объект
  • Используйте BindingUtils для этого программно.

В Flex 4 они вводят новый синтаксис для двунаправленного привязки @{some.binding.expression}, но он недоступен в Flex 3.

Во второй части: ошибка, которую вы получаете, связана с тем, что вы привязываетесь к "универсальному" прототипу Object. Когда вы применяете тег метаданных [Bindable] к свойству или классу, компилятор MXMLC генерирует AS-код, который включает использование утилит привязки и наблюдателей изменения свойств, чтобы сделать привязку. Однако вы не можете сделать прототип Object таким, поскольку он встроен. Вы можете создать собственный класс ActionScript, который можно связывать (или имеет определенные свойства, которые можно связывать). Компилятор MXMLC будет генерировать класс, который реализует IEventDispatcher и, следовательно, поддерживает привязку. Преимущество этого заключается в том, что он быстрее, чем объекты прототипа, а также дает вам проверку времени компиляции, то есть вы получите ошибку компилятора, если ссылаетесь на недопустимое свойство.

Другой вариант - обернуть ваш прототип в ObjectProxy, как предложил один из других членов SO.

Ответ 4

Просто подскажите, как узнать код нарушения в более крупном проекте - поставьте точку останова на два

trace("warning: unable to bind to property '"

в классе SDK PropertyWatcher (Navigate > Open Type > ...). Затем Stacktrace поможет вам найти компонент ui, который содержит сломанную привязку.

Ответ 5

Здесь ссылка livingocs для интерфейса. Это в значительной степени то, что было бы очевидно.

Цитата:

В общем, самым простым способом для определяемого пользователем класса для возможности диспетчеризации событий является расширение EventDispatcher.

Следовательно,

private static const emptyLink: EventDispatcher = {

Ответ 6

В общем, причина, по которой вы получаете "неспособность привязать свойство foo к классу, связана с тем, что вы либо не используете getter, либо setter для foo. Вы также можете сделать foo привязанным к public variable (хотя это и разрушает инкапсуляцию)

Итак, вам нужно, чтобы оба они сделали это:

public function set foo (o:FooObject) : void {
...
}

или

public function get foo() : FooObject {
...
}

Ответ 7

Я не использовал Flex очень долго, и это может не соответствовать вашим требованиям, но почему бы не использовать XML? Я считаю, вы можете установить текстовое значение TextInput для атрибутов в XML.

Я использую псевдокод, но что-то вроде этого имеет смысл для меня:

[Bindable] private static const currentLink:XML = <root>
                                                    <trigger1 value=""/>
                                                    <trigger2 value="" />
                                                  </root>;
...
<mx:TextInput id="trigger1" width ... text="{[email protected]}" />

Что-то вроде этого, возможно?