Flash Galerie...

SonMiko

Erfahrenes Mitglied
Halihallo zusammen...

Ich bin derzeit damit beschäftigt eine Flash-Galerie zu entwickeln.
Ich habe mich dabei für einen Objektorientierten Weg entschieden -
leider stoße ich hier schon an meine Grenzen...

Die Galerie soll über eine XML Datei die nötigen Informationen erhalten,
die Struktur sieht folgendermaßen aus:
Code:
<?xml version="1.0" encoding="utf-8"?>
<pictures>
	<picture id="1" titel="erstes bild" beschreibung="Der Kunde Mercedes..." bild="1.jpg" />
	<picture id="2" titel="zweites bild" beschreibung="BMW - besorg mir Wagen" bild="2.jpg" />
	<picture id="3" titel="drittes bild" beschreibung="Audi? Quattro!" bild="3.jpg" />
</pictures>
</xml>

Dann habe ich zwei Klassen.
Eine für das Gallery-Script, die andere für die einzelnen Bilder.
Mein Ziel ist es für jeden Wert aus der XML Datei ein Bild Objekt zu instanziieren.
Also nicht für JEDEN Wert, sondern viel mehr für einen "Datensatz".
Die einzelnen Objekte haben dann ja Eigenschaften und so weiter... (ich vererbe hier, also bei den Bildern, die MovieClip Eigenschaften und Methoden).

Hier mal die Klasse für die Galerie:
Code:
class gallery extends XML
{
	var anzBX:Number;
	var anzBY:Number;
	var icoxs:Number;
	var icoys:Number;

	function gallery()
	{
		

	}
	
	function src(target)
	{
		ignoreWhite=true;
		load(target);
		var mike:Object = new picture();
		
		onLoad = function(successs)
		{
			
		_root.xmlId = [];
		_root.xmlTitel = [];
		_root.xmlBeschreibung = [];
		_root.xmlBild = [];
		
		if (successs)
		{
		for (var i = 0; i<this.firstChild.childNodes.length; i++) {
		_root.xmlId[i] = this.firstChild.childNodes[i].attributes.id;
		_root.xmlTitel[i] = this.firstChild.childNodes[i].attributes.titel;
		_root.xmlBeschreibung[i] = this.firstChild.childNodes[i].attributes.beschreibung;
		_root.xmlBild[i] = this.firstChild.childNodes[i].attributes.bild;
		}
		}
	}
		
}

Noch sieht man auch nicht viel von den Objekten, da ich bisweilen versuche in Arrays zu speichern... Es handelt sich um ein von mir einmal entworfenes und nun modifiziertes Script...

Eine der Hauptfragen die sich mir stellen:
Wenn ich IN meiner Klasse beim entsprechenden Funktionsaufruf eine XML Datei lade,
brauche ich ja keinen Namen vor die Methode "load" zu setzen (das klappt auch - ich habe mir im debugger die Variablen auflisten lassen und die XML Struktur ist mit drin),
aber was tue ich dann an folgender Stelle:
Code:
this.firstChild.childNodes[i].attributes.id;
Das "this" habe ich einfach einmal dazugeschrieben...
dürfte ich hier auch jegliche Bezeichnung weglassen?

Und: Wichtig für mich wäre zu sehen wie man Objekte Dynamisch erstellt -
irgendwo muss ich ja fortlaufend nummerieren - in Form eines Arrays...
Glaub das ist die wichtigste Frage...

Aktuell sieht die Funktion in der Klasse nun so aus:
Code:
function src(target):XML
	{
		ignoreWhite=true;
		load(target);
		
		onLoad = function(successs)
		{
		if (successs)
		{
		for (var i = 0; i<gallery.firstChild.childNodes.length; i++)
		{
		this["bild"+i]:Object = new picture();
		bild[i].id = gallery.firstChild.childNodes[i].attributes.id;
		bild[i].titel = gallery.firstChild.childNodes[i].attributes.titel;
		bild[i].beschreibung = gallery.firstChild.childNodes[i].attributes.beschreibung;
		bild[i].bild = gallery.firstChild.childNodes[i].attributes.bild;
		}
		}
		}
	}


Würde mich über Lösungsansätze und Hilfe freuen.

Besten Dank,

liebe Grüße,


Euer,

Mike
 
Zuletzt bearbeitet:
Hi,

1. Ich würde - schon aus Gründen der Übersichtlichkeit - immer den Bezeichner "this" voransetzen.

2. Ich hätte hier wohl auch Arrays eingesetzt. Eine Alternative wären z.B. verkettete Listen, die Du dann aber auch selbst implementieren müsstest.

Gruß
.
 
Hallo Tobias,

danke für die Antwort

Gut dann weiss ich bescheid.
Es funktioniert aber wohl scheinbar wenn ich alles weglasse - also auch ohne this.
Registriert sind die Variablen und auch die Objekte des Klasse Picture in der "_global" Variable...

Was mich einfach interessiert ist die Frage: Wie kann ich dynamisch Objekte erstellen?
Bei Arrays klappte das ja immer - und das sind ja eigentlich auch Objekte...
Ich meine mich zu erinnern, dass ich da ungefähr so verfahren bin:
Code:
this["myArray"+i]...;
Aber wie sieht es aus, wenn ich nun explizit ein Objekt der Klasse Picture instanziieren möchte?
Code:
var this["myPic"+i]:Object = new picture(); //?
Oder wie

Besten Gruß und tausend Dank mal wieder...

Mike
 
Hi,

das wird aus dem Grund nicht gehen, da einer Klasse zur Laufzeit keine Member hinzugefügt werden dürfen (zumindest ist das normalerweise bei OOP der Fall, mag sein, das AS2.0 es noch erlaubt).

Eine Klasse des Typs Array wäre "dynamic", würde also das Hinzufügen neuer Member erlauben. Das müsste (aus dem Stehgreif) in etwa so funktionieren
Code:
dynamic class Foo() {
  function addMember(idx:Number):Void {
     this["instance_" + idx] = new Object();
  }
}

Gruß
.
 
Hallo Tobias,

danke für die Antwort.
Aber Du weisst, dass ich aus einer weiteren Klasse instanziieren möchte?
Also ich habe die "gallery.as" Klasse, aus der ich im ersten Frame ein Objekt erschaffe.
Die Methode "src" bekommt einen String welcher den Dateinamen der XML-Datei beinhaltet. Dann liest die Methode die XML-Datei aus und erzeugt eben aus der Klasse "picture.as" einzelne Objekte.
Diese sind doch dann nicht Teil der Klasse "gallery" - weil auch beim Debuggen werden bei den Variablen-Auflistungen angezeigt, dass Objekte die ich in dieser Klasse "gallery" aus der Klasse "picture" erschaffe, zur Variablen "_global" gehören - ich meine sonst würde doch dort irgendwo eine art Verkettung bestehen...
Für mich wäre es logisch, das ich nicht aus der Galerie eine weitere erschaffen kann, also nicht intern - das wäre logisch und denkbar, aber theoretisch kann ich doch so viele Objekte aus anderen Klassen erschaffen wie ich möchte, oder nicht?

Das Präfix "dynamic" bekommt eine Klasse doch nur, wenn ich jetzt beispielsweise im ersten Frame, dort wo ich das Galerie-Objekt erschaffe, dem Objekt weitere Eigenschaften zufügen wollte - oder Methoden.
Das hat doch etwas mit der Typisierung zu tun:
Code:
var myGal:Object = new Object() //Nicht korrekt typisiert - funktioniert zwar, aber theoretisch kann ich Eigenschaften oder Methoden abfragen oder festlegen, die es nicht gibt
var myGal:Object = new gallery() //Korrekt typisiert - Flash weiss, dass es nur bestehende Eigenschaften und Methoden verwenden darf/ soll, alles andere führt zu einem Fehler: AUSSER ich gebe der Klasse den Wert "dynamic".

Das Void würde ich in meinem Fall sogar weglassen, da ich ja einen Rückgabewert erhalte - oder nicht?
Da würde ich doch anders typisieren (mag aber auch sein das ich mich irre)

Besten Gruß,

Mike
 
Zuletzt bearbeitet:
Hi,

mit AS2.0 brauchst Du anscheinend tatsächlich nicht den Typ "dynamic", um zur Laufzeit Objekte hinzuzufügen.

Probier mal folgendes (exemplarisch und daher nur grob an Deinem Beispiel angelehnt):
Code:
class Image extends MovieClip {
	
	private var _src:String;
	
	public function Image(src:String) {
		this._src = src;
		trace("Ich bins: " + _src);
	}
	
	public function getSrc(Void):String {
		return this._src;
	}
}
Code:
import Image;

class Gallery extends MovieClip {
	
	private var _counter:Number;
	
	public function Gallery() {
		this._counter = 0;
	}
	
	public function addImage(src:String):Void {
		var obj:Image = new Image(src);
		this["image_" + this._counter] = obj;
		this._counter ++;
	}
	
	public function listImages(Void):Void {
		for (var i:Number=0; i<this._counter; i++) {
			trace("Bild " + i + ": " + this["image_" + i].getSrc());
		}
	}
}
Code:
import Gallery;
import Image;

var gal:Gallery = new Gallery();

gal.addImage("bild1.jpg");
gal.addImage("bild2.jpg");
gal.addImage("bild3.jpg");
gal.addImage("bild4.jpg");

gal.listImages();

Du würdest folgende Ausgabe erhalten:
Code:
Ich bins: bild1.jpg
Ich bins: bild2.jpg
Ich bins: bild3.jpg
Ich bins: bild4.jpg
Bild 0: bild1.jpg
Bild 1: bild2.jpg
Bild 2: bild3.jpg
Bild 3: bild4.jpg

Statt in einem Array werden alle Bilder als einzelne Member des Objekts "Gallery" angelegt.

Gruß

P.S.: Die Funktion "addMember" aus meinem vorherigen Beispiel gibt keinen Wert zurück (kein return angegeben), daher der Datentyp "Void".
.
 
Hallo Tobias,

danke für die Antwort und den damit verbundenen Zeitaufwand
Ich werde das ganze gleich mal testen.


Vorab vielen Dank.

Besten Gruß,

Mike
 
Hi Tobias,

bei mir klappt das ganze nun, also ich erzeuge dynamisch einzelne Picture-Objekte...
Eins stört mich aber nun doch noch:
Ich kann NICHT die Methode "loadMovie" ausführen.
Wenn ich eine eigene Methode in der Picture Klasse erstelle (sag mal, an dieser Stelle, wie kann ich den Code als Actionscript Code darstellen - also wie lautet die Syntax dazu?):
Code:
class picture extends MovieClip
{
	var id:Number;
	var	titel:String;
	var	beschreibung:String;
	var	bild:String;
	
	function picture()
	{
		
	}
	
	function ausgabe()
	{
		trace(id);
		trace(titel);
		trace(beschreibung);
		trace(bild);
	}
	
	function imgload(target:String,id:Number)
	{
		loadMovie(target,id);
	}
}
Bei der Funktion "imgload" habe ich schon sämtliche Sachen versucht, und ich erhalte jedes mal in der Ausgabe:
"Typdiskrepanz".
Was mache ich falsch?

Besten Gruß,

Mike
 
Hi,

was steht denn in "target" und "id"?

Ich würde den Container zum Einladen der Bilddatei in der Instanz von "Image" unterbringen, und die loadMovie-Methode des MovieClip-Objekts (oder, noch besser: den MovieClipLoader) verwenden:
Code:
class Image extends MovieClip {
	
	private var _src:String;
	private var _ct:MovieClip;
	private var _mcl:MovieClipLoader;
	
	public function Image() {
		this._ct = this.createEmptyMovieClip("_ct", this.getNextHighestDepth());
		this._mcl = new MovieClipLoader();
		this._mcl.onLoadInit = function() {
			trace("fertig");
		}
	}

	public function loadImage(src:String):Void {
		this._mcl.loadClip(src, this._ct);
	}
}

Gruß
.
 
Zurück