Avatar billede Slettet bruger
29. december 2007 - 14:53 Der er 7 kommentarer og
1 løsning

Hvorfor er funktionerne 'out of scope'

Hej Flash-haj.

Prøv lige at se nedenstående kodeudsnit (jeg bruger Adobe remoting-komponenten og AMFPHP ver. 1.2) - koden virker som den skal:

if (fejl == false) {
  var _service:Service = new Service(gatewayUrl, null, 'Logind', null, null);
  var pc:PendingCall = _service.say(this.brugernavn, this.kodeord);
  pc.responder = new RelayResponder(this, "handleResult", "handleError");
}
function handleResult(re:ResultEvent) {
  trace("Denne BLIVER kaldt: "+re.result);
}
function handleError(fe:FaultEvent) {
  trace('Fejl!');
}

Prøv så at se DENNE kode:

if (fejl == false) {
  var _service:Service = new Service(gatewayUrl, null, 'Logind', null, null);
  var pc:PendingCall = _service.say(this.brugernavn, this.kodeord);
  pc.responder = new RelayResponder(this, "handleResult", "handleError");
  function handleResult(re:ResultEvent) {
    trace("Denne bliver ikke kaldt - hvorfor ikke?!?!?: "+re.result);
  }
  function handleError(fe:FaultEvent) {
    trace('Fejl');
  }
}

Jeg fandt ud af, at modtagefunktionerne skulle sættes udenfor if-sætningen - men jeg kunne godt tænke mig at vide, HVORFOR den nederste ikke fungerer... for en alm. if-sætning burde da ikke sætte funktionerne ude af scope, vel?!?
Avatar billede snakeeye Nybegynder
29. december 2007 - 15:21 #1
Nu har jeg ikke alt for meget kendskab til flash men, i alm programmering kan man ikke lave en funktion inde i et scope ala en if sætning. Jeg undre mig over hvorfor du ikke får en fejl når du compiler det.
Avatar billede nielle Nybegynder
29. december 2007 - 15:27 #2
Når funktionerne er defineret inde i if-sætningen så er deres scope begrænset til imellem de to {...} parenteser. De er ikke kendte udenfor. Dermed kan RelayResponder() heller ikke finde dem når den skal lave callback til dem.
Avatar billede barklund Nybegynder
29. december 2007 - 15:53 #3
Nej, funktionerne er ikke begrænset inden for blokken {} i if-sætningen! Snakeeye har faktisk ret i, at det kan man slet ikke - og at det er noget bøvl at kompileren ikke siger noget. Men det er der nu tradition for inden for Flash-compilere (wink-wink macromedia!)

Alle funktioner defineret som function foo(){} bliver ved kompilering flyttet op øverst i den frame, hvor de står. Funktioner der derfor er defineret inden i en blok begrænset af en betingelse (if, else, for, while, etc) fjernes helt, for de kan jo ikke flyttes op, men kompileren kan heller ikke kompilere dem hvor der er.

a = true;
if (a) {
  function f() { return "a"; }
} else {
  function f() { return "b"; }
}
f();

Der kommer intet output - for f findes slet ikke. Funktionerne defineret inde i blokkene slettes helt (uden advarsel endda fra kompileren).

Kig i min bog (http://www.globe.dk/TradePoint/Item_View?itemNo=FG227-2) i kapitlet om funktioner, hvis I vil vide mere - dette gennemgås helt i bund og godt nok er den skrevet til flash 6, men disse ting har ikke ændret sig op igennem actionscript 1 og 2. ActionScript 3 er også på dette punkt noget helt andet, så her er den ikke gældende længere.

For at vende tilbage til spørgsmålet. I stedet for at "overskrive" definitionen af samme funktion "handleResult" hver gang, så brug da bare forskelligt navngivne funktioner og skriv den enkelte i den enkelte RelayResponder:

if (fejl == false) {
  var _service:Service = new Service(gatewayUrl, null, 'Logind', null, null);
  var pc:PendingCall = _service.say(this.brugernavn, this.kodeord);
  pc.responder = new RelayResponder(this, "handleLogin", "handleLoginError");
}
...
function handleLogin(re:ResultEvent) {
  trace("login er gennemført: "+re.result);
}
function handleLoginError(fe:FaultEvent) {
  trace('Fejl ved login');
}

Det er den rigtige måde at gøre det på. Eller i hvert fald rigtigere - OOP ville være endnu pænere :)

--
Morten Barklund
Avatar billede Slettet bruger
29. december 2007 - 16:32 #4
Tusind tak for svar :-) Og tak for den grundige gennemgang, Morten Barklund.
Jeg har smidt lidt flere point på, så Snakeeye og Barklund, hvis I lige poster som svar...
Avatar billede snakeeye Nybegynder
29. december 2007 - 16:37 #5
bare smid point'ene til barklund for den gennemgang
Avatar billede barklund Nybegynder
29. december 2007 - 17:10 #6
Jeg håber du finder ud af at strukturere det lidt om - og skynd dig at købe et eksemplar af ovenstående, første oplag er næsten udsolgt ;)
Avatar billede Slettet bruger
29. december 2007 - 17:28 #7
Super - her er i øvrigt projektet, jeg roder med. Det er stadig kun halvfærdigt (diverse fejl inklusive), men der kommer mere som dagene skrider frem...

http://www.innova2r.net/versionfinale
Avatar billede barklund Nybegynder
29. december 2007 - 22:55 #8
Tark for points - og det ser nydeligt ud, men transitionerne skal speedes op, så man ikke bliver for træt af det. Jeg ved godt, at de bedre ses når det går langsomt, men det bliver for tungt at bruge i praksis :)

(derudover er jeg kun nørd og langt fra grafiker eller usability-ekspert)

:)

--
Morten Barklund
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester