Two-way Data Binding – Flex 4

Two-way data binding é uma das novidades do flex 4 e para quem não conhece, vou mostrar como funciona e o que mudou em relação ao Flex 3.

No Flex 3 tinhamos data binding de apenas uma via, como mostra o exemplo abaixo:

1
2
<mx:TextInput id="tiValor1"/>
<mx:TextInput id="tiValor2" text="{tiValor1.text}"/>

Nesse exemplo, caso o valor da caixa de texto do tiValor1 mudasse, o valor da caixa de texto do tiValor2 seria alterado também, porém, se o valor da caixa tiValor2 fosse alterado, nada seria refletido a caixa de texto tiValor1.

No Flex 4 temos data binding de duas vias, como mostra o exemplo:

1
2
<s:TextInput id="tiValor1"/>
<s:TextInput id="tiValor2" text="@{tiValor1.text}"/>

Nesse exemplo notamos que a anotação “@” foi colocada antes do meu código “{tiValor1.text}”, essa anotação identifica um data binding de duas vias. O resultado desse exemplo é: Caso eu altere o texto da caixa de texto tiValor1, ele será refletido na caixa de texto tiValor2, e vice-versa.

Obviamente esse exemplo da funcionalidade é muito básico e serve apenas para demonstrar a funcionalidade, logo vou apresentar uma situação real que acontece a todo momento em qualquer aplicação.

Para o nosso exemplo real, vou utilizar uma situação comum para qualquer tipo de aplicação, o CRUD. Para todo CRUD precisamos sempre fazer essas 3 operações:
1. Mostrar o objeto carregado do back-end nas caixas de texto. (Famoso método carregaObjeto)
2. Atualizar o objeto com os novos valores das caixas de texto. (Famoso método preencherObjeto)
3. Limpar as caixas de textos. (Famoso método limpar)

No flex 3 teriamos o seguinte cenário.
Para a situação 1:
caixaDeTexto.text = Objeto.valor;
Para a situação 2:
Objeto.valor = caixaDeTexto.text;
Para a situação 3:
caixaDeTexto.text = “”;

Para quem usava o data binding do flex 3 de uma forma correta, conseguia resolver uma das situações com ele, mas nas outras situações sempre acabava escrevendo a linha de código apresentada.

No flex 4 poderiamos resolver da seguinte forma:

1
<s:TextInput id="caixaDeTexto" text="@{Objeto.valor}"/>

Com essa simples mudança, nós evitaríamos todas as situações acima, dispensando os métodos de carregarObjeto, preencherObjeto e limpar objeto.

Veja o exemplo funcional abaixo:




Fonte:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark" maxHeight="400" maxWidth="600"
               xmlns:mx="library://ns.adobe.com/flex/mx" width="600" height="400" xmlns:local="*">
    <fx:Declarations>
        <local:User id="user">
            <local:id>1</local:id>
            <local:nome>Bruno Sales</local:nome>
            <local:cidade>São Paulo</local:cidade>
        </local:User>
    </fx:Declarations>

    <fx:Script>
        <![CDATA[
            private function recarregar():void
            {
                user = new User("1", "Bruno Sales", "São Paulo");
            }
        ]]>
    </fx:Script>

    <s:layout>
        <s:HorizontalLayout verticalAlign="middle" horizontalAlign="center"/>
    </s:layout>

    <s:Panel title="Form" width="250" height="180">
        <mx:Form>
            <mx:FormItem label="Id">
                <s:TextInput id="tiValor1" text="@{user.id}" maxChars="20"/>
            </mx:FormItem>
            <mx:FormItem label="Nome">
                <s:TextInput id="tiValor2" text="@{user.nome}" maxChars="20"/>
            </mx:FormItem>
            <mx:FormItem label="Cidade">
                <s:TextInput id="tiValor3" text="@{user.cidade}" maxChars="20"/>
            </mx:FormItem>
            <mx:FormItem horizontalAlign="right">
                <s:Button label="Limpar" click="user = new User()"/>
            </mx:FormItem>
        </mx:Form>
    </s:Panel>

    <s:Panel title="Objeto User" width="300" height="180">
        <s:layout>
            <s:VerticalLayout verticalAlign="middle" horizontalAlign="center"/>
        </s:layout>
        <s:Label id="label" text="{user.toString()}"/>
        <s:Button label="Recarregar Objeto" click="recarregar()"/>
    </s:Panel>

</s:Application>

8 comments

  1. Leonardo on 25.fev.11 at 2:57 pm

    Post muito bom, só podia falar mais sobre quando a propriedade do objeto for do tipo int ou number.

  2. João Felipe - Jotaefe on 26.fev.11 at 12:27 am

    Muito bom Bruno,

    Este novo recurso realmente é uma mão na roda hehe, gostei do exemplo que utilizou para demonstrar a utilização, parabéns.

    Abraços,

  3. Bruno Ferreira on 1.mar.11 at 7:57 am

    Bom dia Bruno,
    Primeiramente parabéns pelo post, realmente se trata de um recurso bastante útil, além de muito interessante.
    Eu gostaria de saber se existe a possibilidade de implementar o Data Binding de duas vias em declarações e/ou criações de componentes via action script.
    Para ficar mais claro veja o exemplo abaixo.

    txtAbreviacao=new TextInput();
    txtAbreviacao.maxChars=25;
    txtAbreviacao.text = ???
    frmItem.addChild(txtAbreviacao);

    O que teria de ser colocado na propriedade “text” do TextInput para que tivesse o mesmo resultado do seu exemplo?

    Grato pela atenção.

  4. Bruno Sales on 3.mar.11 at 9:04 am

    @Bruno Ferreira

    Eu tentei ver o AS que é gerado quando utilizamos two-way data binding porém ele é bem extenso e confuso, precisaria de mais tempo para enteder e extrair o necessário.
    Caso você queira ver como ele se comporta, faça o exemplo citado e compile com o argumento -keep-generated-actionscript.

  5. Joel Backschat on 1.set.11 at 12:09 am

    Muito bom a DCLICK como sempre de parabéns.

Trackbacks

  1. Tweets that mention Two-way Data Binding – Flex 4 | DClick Team Weblog [pt] -- Topsy.com
  2. Two-way Data Binding – Flex 4 – Problema de Conversão de Tipo | DClick Team Weblog [pt]
  3. Two-way Data Binding – Flex 4 – Objetos complexos em componentes de lista | DClick Team Weblog [pt]

Leave a Comment