Vra

Ek het net gedoen om'n bietjie van die Bult-ontwikkeling so ver, maar ek het verkies die benadering van die skep van beheer programmaties oor mxml lêers, omdat (en asseblief, korrigeer my as ek verkeerd is!) Ek versamel het dat jy nie kan dit beide maniere-dit is om te sê, het die klas funksies in'n aparte Action klas lêer, maar het die elemente vervat verklaar in mxml.

Daar lyk nie te veel van'n verskil produktiwiteit-wyse, maar om data bindend programmaties lyk ietwat minder as triviale.Ek het'n blik op hoe die mxml samesteller verander die data bindend uitdrukkings.Die resultaat is'n klomp van die gegenereerde verificaties en'n baie meer lyne as in die mxml verteenwoordiging.So hier is die vraag: is daar'n manier om dit te doen data bindend programmaties wat behels nie'n wêreld van seer?

Was dit nuttig?

Oplossing

Moenie bang wees vir MXML wees. Dit is wonderlik vir die uitleg van standpunte. As jy jou eie skryf herbruikbare komponente dan skryf hulle in Action soms gee jy 'n bietjie meer beheer, maar vir nie-herbruikbare uitsig MXML is baie beter. Dit is meer kortaf, bindings is extemely maklik op te rig, ens.

Maar bindings in suiwer Action hoef nie veel van 'n pyn wees. Dit sal nooit so eenvoudig soos in MXML waar 'n klomp dinge vir jou gedoen word, maar dit kan gedoen word met nie te veel moeite.

Wat jy is BindingUtils en dis metodes bindSetter en bindProperty. Ek het amper altyd gebruik die voormalige, want ek gewoonlik wil om werk te doen, of bel invalidateProperties wanneer waardes verander, het ek amper nooit wil net 'n eiendom te stel.

Wat jy moet weet, is dat hierdie twee terugkeer 'n voorwerp van die tipe ChangeWatcher, as jy wil hê dat die bindende vir een of ander rede verwyder, moet jy om vas te hou aan hierdie voorwerp. Dit is wat maak handleiding bindings in Action 'n bietjie minder gerieflik as dié in MXML.

Kom ons begin met 'n eenvoudige voorbeeld:

BindingUtils.bindSetter(nameChanged, selectedEmployee, "name");

Dit stel 'n bindende dat die metode nameChanged sal bel wanneer die eiendom name op die voorwerp in die veranderlike selectedEmployee veranderinge. Die nameChanged metode sal die nuwe waarde van die eiendom name as 'n argument te ontvang, sodat dit moet lyk soos volg:

private function nameChanged( newName : String ) : void 

Die probleem met hierdie eenvoudige voorbeeld is dat wanneer jy die opstel van hierdie bindwerk dit sal elke keer afgegaan die eiendom van die gespesifiseerde voorwerp verander. Die waarde van die veranderlike selectedEmployee kan verander, maar die bindende is nog vir die opstel van die voorwerp wat die veranderlike wys na voor.

Daar is twee maniere om hierdie op te los: óf om die ChangeWatcher teruggekeer deur BindingUtils.bindSetter om te hou en te bel unwatch op dit wanneer jy wil die binding (en dan die opstel van 'n nuwe binding plaas) te verwyder, of bind aan jouself. Ek sal jou wys die eerste opsie eerste, en dan verduidelik wat ek bedoel deur binding aan jouself.

Die currentEmployee kan gemaak word in 'n lucky / setter paar en geïmplementeer soos hierdie (net wat die setter):

public function set currentEmployee( employee : Employee ) : void {
    if ( _currentEmployee != employee ) {
        if ( _currentEmployee != null ) {
            currentEmployeeNameCW.unwatch();
        }

        _currentEmployee = employee;

        if ( _currentEmployee != null ) {
            currentEmployeeNameCW = BindingUtils.bindSetter(currentEmployeeNameChanged, _currentEmployee, "name");
        }
    }
}

Wat gebeur is dat wanneer die eiendom currentEmployee is ingestel dit lyk om te sien of daar 'n vorige waarde, en as die bindende vir daardie voorwerp (currentEmployeeNameCW.unwatch()) so verwyder, dan sit dit die private veranderlike, en tensy dit uit die nuwe waarde was null stel 'n nuwe binding vir die eiendom name. Die belangrikste is dit spaar die ChangeWatcher teruggekeer deur die bindende oproep.

Dit is 'n basiese binding patroon en ek dink dit werk goed. Daar is egter 'n truuk wat gebruik kan word om dit 'n bietjie makliker te maak. Jy kan bind om jouself plaas. In plaas van die opstel en die verwydering van bindings elke keer as die eiendom currentEmployee verander kan jy die bindende stelsel het dit vir jou doen. In jou creationComplete hanteerder (of constructor of ten minste 'n paar keer vroeg) kan jy die opstel van 'n bindende soos so:

BindingUtils.bindSetter(currentEmployeeNameChanged, this, ["currentEmployee", "name"]);

Dit stel 'n bindende nie net om die eiendom currentEmployee op this, maar ook om die eiendom name op hierdie voorwerp. So enige tyd óf verander die metode currentEmployeeNameChanged sal genoem word. Daar is geen behoefte om die ChangeWatcher red omdat die binding sal nooit weer hoef te verwyder.

Die tweede oplossing werk in baie gevalle, maar ek het gevind dat die eerste een is soms nodig, veral wanneer daar met bindings in 'n nie-oog klasse (sedert this het om 'n gebeurtenis planner wees en die currentEmployee het bindable te wees vir dit om te werk).

Ander wenke

Dit bestaan as van vandag.:)

Ek het sopas my Action data bindend projek as open source: http://code.google.com/p/bindage-tools

BindageTools is'n alternatief vir BindingUtils (sien die speel op woorde daar?) wat gebruik maak van'n vlot API waar jy verklaar jou data bindings in'n pyplyn styl:

Bind.fromProperty(person, "firstName")
    .toProperty(firstNameInput, "text");

Twee-manier bindings:

Bind.twoWay(
    Bind.fromProperty(person, "firstName"),
    Bind.fromProperty(firstNameInput, "text"));

Eksplisiete data-omskakeling en validering:

Bind.twoWay(
    Bind.fromProperty(person, "age")
        .convert(valueToString()),
    Bind.fromProperty(ageInput, "text")
        .validate(isNumeric()) // (Hamcrest-as3 matcher)
        .convert(toNumber()));

Ens.Daar is baie meer voorbeelde op die webwerf.Daar is baie van die ander funksies te kom kyk.--Mattheus

Edit:opgedateer APIs

Een manier om die MXML en Action skei vir 'n komponent in afsonderlike lêers is deur iets soortgelyk aan die ASP.Net 1.x kode agter model doen. In hierdie model die verklarende deel (die MXML in hierdie geval) is 'n subklas van die noodsaaklikheid deel (die Action). So kan ek agter verklaar die kode vir 'n klas soos volg:

package CustomComponents
{
    import mx.containers.*;
    import mx.controls.*;
    import flash.events.Event;

    public class MyCanvasCode extends Canvas
    {
        public var myLabel : Label;

        protected function onInitialize(event : Event):void
        {
            MyLabel.text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit.";
        }
    }
}

... en die opmaak soos volg:

<?xml version="1.0" encoding="utf-8"?>
<MyCanvasCode xmlns="CustomComponents.*" 
    xmlns:mx="http://www.adobe.com/2006/mxml"
    initialize="onInitialize(event)">
    <mx:Label id="myLabel"/>    
</MyCanvasCode>

Soos jy kan sien uit hierdie voorbeeld, 'n disadvatage van hierdie benadering is dat jy hoef te beheer soos verklaar mylabel in beide lêers.

Daar is 'n manier dat ek gewoonlik gebruik om mxml en aksie script saam gebruik: Al my mxml komponente besit van 'n aksie script klas waar ek voeg die meer komplekse kode. Dan kan jy verwys na gebeurtenis luisteraars in hierdie klas geïmplementeer in die mxml lêer.

Groete,

Ruth

Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top