Flex Aviso: Não é possível vincular a propriedade 'foo' em 'Objeto' class (classe não é uma IEventDispatcher)

StackOverflow https://stackoverflow.com/questions/928081

Pergunta

Eu tenho um objeto que contém uma dúzia de campos Quero ligam a elementos de formulário, para que eu possa usar esse objeto para enviar a de volta dados para o servidor para ser salva.

Definição do meu objeto container:

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 é atribuído em tempo de execução para um índice específico de uma ArrayCollection, eu só estou usando o objeto emptyLink para inicialização fins, principalmente.

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

Claro, isso compila e exibe muito bem, mas há avisos de tempo de execução para cada instância:

Atenção: não é possível vincular a propriedade 'trigger1' na classe 'Object' (classe não é uma IEventDispatcher) Aviso: Não é possível vincular a propriedade 'trigger2' na classe 'Object' (classe não é uma IEventDispatcher) Aviso: Não é possível vincular a propriedade 'trigger3' na classe 'Object' (classe não é uma IEventDispatcher) Aviso: Não é possível vincular a propriedade 'trigger4' na classe 'Object' (classe não é uma IEventDispatcher) aviso: não foi possível vincular a propriedade 'trigger5' na classe 'Object' (classe não é uma IEventDispatcher)

E o objeto currentLink não é atualizada quando os campos TextInput são alterados.

A resposta óbvia é que o meu objeto precisa ser uma instância de uma classe que implementa IEventDispatcher. O que essa resposta não me diz é os detalhes de implementação dessa interface, e se há uma maneira simples de fazer isso (o que é necessário o que não é?) - como um construído em classe que vai aceitar de bom grado minhas propriedades personalizadas e permitir para a ligação, sem me ter de se preocupar com os detalhes de implementação da interface.

O tal exist classe? Se não, qual é o padrão aceito mínimo e / ou para realizar esta tarefa?

Foi útil?

Solução

Você precisa usar ObjectProxy (como Chetan menciona) - mas você também precisa usar valueCommit para obter o texto inserido na parte de trás de entrada em seu objeto:

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

Outras dicas

Object não despacha eventos. Apesar de ter feito a variável Bindable, as propriedades do objeto referenciado pelo currentLink variável não pode ser vinculado.

Use ObjectProxy vez.

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

A primeira coisa que você vai querer saber é que obrigatório em Flex 3 não é bidirecional. A expressão de ligação irá assegurar que, se a fonte da expressão de ligação (currentLink.trigger1) muda que o alvo (TextInput) receberá a notificação da alteração e actualização em conformidade. Se você quiser a ligação para ir em outra direção, há pelo menos duas maneiras de fazer isso:

  1. Use o mx: Binding tag para trás TextInput.text direto ao objeto
  2. Use BindingUtils fazer isso programaticamente vez.

Em Flex 4 eles estão introduzindo uma nova sintaxe para a ligação bidirecional @ {some.binding.expression}, mas ele não está disponível em Flex 3.

Na 2ª parte: o erro que você está recebendo é porque você está ligando a um "genérico" protótipo Objeto. Quando você aplica a tag [Bindable] metadados para uma propriedade ou classe, o compilador mxmlc gera AS código que inclui o uso de utilitários de ligação e observadores de alteração de propriedade de fazer fazer a ligação acontecer. No entanto, você não pode fazer o objeto de protótipo fazer isso, já que é um built-in. Você pode criar uma classe ActionScript personalizado que é bindable (ou tem certas propriedades bindable). O compilador mxmlc irá gerar uma classe que implementa IEventDispatcher e, portanto, suporta ligação. Isto tem a vantagem de ser mais rápido do que objetos de protótipo e também lhe dá tempo de compilação verificação, ou seja, você receberá um erro do compilador se você faz referência uma propriedade inválida.

A outra alternativa é envolver o seu protótipo em ObjectProxy como um dos outros membros por isso tem sugerido.

Apenas uma dica sobre como descobrir o código incorreto em um projeto maior - colocar um ponto de interrupção em dois

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

linhas na classe PropertyWatcher do SDK (Navegar> Tipo Abrir> ...). Stacktrace irá ajudá-lo a encontrar o componente ui que mantém o quebrado vinculativo.

Em geral, a razão pela qual você obtém "incapaz de se ligam a foo propriedade em uma classe, é porque você está ou faltando um getter ou setter para foo . Você poderia também fazer foo escopo para uma variável pública, (embora este quebras de encapsulamento)

Então, você precisa de ambos para fazer isso ir embora:

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

ou

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

Eis as livedocs referência para a interface. É muito bonito o que seria óbvio.

Para citar:

Em geral, a maneira mais fácil para uma classe definida pelo usuário para obter capacidades de despacho de eventos é estender EventDispatcher.

Assim,

private static const emptyLink: EventDispatcher = {

Eu não tenho usado Flex por muito tempo, e isso pode não atender às suas necessidades, mas por que não usar XML? Eu acredito que você pode definir o valor de texto TextInput a atributos no XML.

Eu estou usando pseudo-código, mas algo como isto faz sentido para mim:

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

Algo assim, talvez?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top