2009-05-29 1 views
22

У меня есть объект, который содержит дюжину полей, которые я хочу связать, чтобы сформировать элементы, так что я может использовать этот объект для отправки данных обратно на сервер, который будет сохранен.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» на классе «Объект» (класс не IEventDispatcher) предупреждение: невозможно связать с свойством «trigger2» в классе «Object» (класс не является IEventDispatcher) предупреждение: невозможно связать с свойством «trigger3» в классе «Object» (класс не является IEventDispatcher) предупреждение: невозможно связать свойство «trigger4» с классом «объект» (класс не является IEventDispatcher) предупреждение: не удалось связать свойству «trigger5» на «Object» класса (класс не является IEventDispatcher)

И объект currentLink не обновляется, когда TextInput поля изменяются.

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

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

ответ

15

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

<?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> 
0

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

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

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

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

8

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

Вместо этого использовать ObjectProxy.

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

Here's the livedocs reference для интерфейса. Это в значительной степени то, что было бы очевидно.

процитировать:

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

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

частных статических Const emptyLink: EventDispatcher = {

+0

Ваша ссылка не идет на страницу в пределах жилых документов, которые вы так и думали. На каждой странице ссылок liveocs в нижнем колонтитуле есть ссылка «Текущая ссылка: ...» с URL-адресом для прямой ссылки на просматриваемую страницу. Используйте это. :) –

4

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

  1. Используйте тх: Привязка метки направить TextInput.text обратно на объект
  2. Использование BindingUtils сделать это программно.

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

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

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

+0

Если бы я мог принять 2 ответа, это было бы # 2. Я выбрал Габриэля, потому что это было самое простое решение сделать то, что я пытаюсь сделать. Спасибо за всю информацию, хотя! –

1

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

Так что вам нужно оба из них, чтобы сделать его уйти:

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

или

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

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

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

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