Wie kommt das HTML Markup auf den Bildschirm?

Klassen kennen 11 "magische" Methoden, die bei der Erstellung von Objekten automatisch aufgerufen werden. Der Mechanismus entspricht den "magic functions" der PHP OOP. Das unten stehende Beispiel benutzt 8 davon. Zwei weitere Möglichkeiten werden hier erklärt. Für die letzte Möglichkeit gibt es eine eigene Demonstration.

Um die "magischen" Methoden zu verstehen, muss man erst verstehen, wie ein Objekt, welches sichtbar sein soll, generell dargestellt wird. Hier ein Beispiel für die einfachste Version einer Klasse die im UI sichtbar ist.


	app.newClass("simpleClass","content",function(param,app,superClass){this.classType="simpleClass"})
	
	app.newObject("simpleClass")
	

Diese Klasse und dieses Objekt erzeugen folgendes HTML:


	<div id="$kvr861$" style="width: auto; height: 490px; " class="app-static app-simpleClass app-object">
		<div id="$kvr861$content" class="app-content" style="width: auto; height: 490px; "></div>
	</div>
	

Es wird also ein "div"-Element für das Objekt und ein "div"-Element für den "Content"-Bereich erzeugt. Hieraus ergeben sich deswegen die 8 "magischen" Methoden:


	this.wrapOpenHTML=function(param,$this$)
	{
		return [];
	}
	

Markup wird vor dem Objekt eingefügt. Sehr limitierte Anwendung, da es als Teil des Objekts außerhalb liegt. Hier bieten sich eigentlich nur positionierte Element an.


	this.objectOpenHTML=function(param,$this$)
	{
		return [];
	}
	

Markup folgt direkt als erstes innerhalb des Objekt-"Wrappers".


	this.bodyOpenHTML=function(param,$this$)
	{
		return [];
	}
	

Markup wird vor den Content-"Wrapper" eingefügt.


	this.contentOpenHTML=function(param,$this$)
	{
		return [];
	}
	

Markup folgt direkt als erstes innerhalb des Content-"Wrappers".


	this.contentCloseHTML=function(param,$this$)
	{
		return [];
	}
	

Markup wird vor dem Ende des Content-"Wrappers" eingefügt.


	this.bodyCloseHTML=function(param,$this$)
	{
		return [];
	}
	

Markup wird hinter dem Ende des Content-"Wrappers" eingefügt.


	this.objectCloseHTML=function(param,$this$)
	{
		return [];
	}
	

Markup wird vor dem Ende des Objekt-"Wrappers" eingefügt.


	this.wrapCloseHTML=function(param,$this$)
	{
		return [];
	}
	

Markup wird hinter dem Ende des Objekt-"Wrappers" eingefügt. Wieder nur sehr limitierte Anwendungsmöglichkeiten.

Das Beispiel

Das Beispiel zeigt, was geschieht, wenn 2 Klassen mit diesen "magischen" Methoden kombiniert werden. Ich habe hier nur eine Klasse benutzt und diese bei der Objekt-Erzeugung mit sich selber kombiniert:


	app.newObject("view.view")	
	

Dies erzeugt, neben der schon definierten Klasse "view", eine 2te Klasse "view.view". Normalerweise sollte jetzt Panik ausbrechen, weil die Vermutung nahe liegt, dass die einzelnen IDs der erzeugten Elemente kollidieren. Zur Beruhigung kann gesagt werden, dass das UI dafür sorgt, dass innerhalb einer Klasse, über die in der Klasse angegebenen IDs, weiterhin auf diese Elemente zugegriffen werden kann. Zuordnungen von Größenangaben relativ zu Elementen, Angaben von CSS Klassen etc. bleiben auch korrekt erhalten, wenn per DOM-Reset neue Elemente mit gleichen IDs hinzugefügt werden. Das einzige worauf man achten muss, ist dass man innerhalb einer Klassendefinition eine ID nicht zweimal benutzt, was aber selbstverständlich sein sollte.

Über die Checkboxen können die einzelnen "magischen" Methoden dazu gebracht werden Markup zurückzugeben. Durch einen "DOM Reset" wird dann eine Neudarstellung ausgelöst.

Rot umrandete Elemente gehören zur Klasse "view".
Blau umrandete Elemente gehören zur Klasse "view.view".

Die Reihenfolgen der Elemente entsprechen also dem normalen "flow", wie er von HTML bekannt ist. Wie dies durch das erweiterte "Namespace"-System unterstützt wird und wie Klassen zusammen spielen, wird hier erklärt.

Beispiel:

Skript:


	app.newClass("view","movedock",function(param,app,superClass){
	
		this.classType="view"
		this.check=function(eO,$this$)
		{
			var c=eO.target.className.substr(4)
			this[c]=!this[c]
			app.content.resetDOM.call(this)
		}
		
		this.wrapOpenHTML=function(param,$this$)
		{
			return [
				(this.superClass!==$this$.superClass || this.wrapOpenCheck)?{
					style:"width:auto;",
					tagName:"div",
					$id$:"wrapOpen",
					className:(this.superClass===$this$.superClass)?"view_class":"view_view_class",
					children:["wrapOpenHTML Class: "+$this$+" Object: "+this]
				}:null
			];
		}

		this.objectOpenHTML=function(param,$this$)
		{
			return [
				(this.superClass!==$this$.superClass || this.objectOpenCheck)?{
					style:"width:auto;",
					tagName:"div",
					$id$:"objectOpen",
					className:(this.superClass===$this$.superClass)?"view_class":"view_view_class",
					children:["objectOpenHTML Class: "+$this$+" Object: "+this]
				}:null
			];
		}
		
		this.bodyOpenHTML=function(param,$this$)
		{
			return [
				(this.superClass!==$this$.superClass || this.bodyOpenCheck)?{
					style:"width:auto;",
					tagName:"div",
					$id$:"bodyOpen",
					className:(this.superClass===$this$.superClass)?"view_class":"view_view_class",
					children:["bodyOpenHTML Class: "+$this$+" Object: "+this]
				}:null
			];
		}
			
		this.contentOpenHTML=function(param,$this$)
		{
			return [
				(this.superClass!==$this$.superClass || this.contentOpenCheck)?{
					style:"width:auto;",
					tagName:"div",
					$id$:"contentOpen",
					className:(this.superClass===$this$.superClass)?"view_class":"view_view_class",
					children:["contentOpenHTML Class: "+$this$+" Object: "+this]
				}:null
				,(this.superClass!==$this$.superClass)?null:[
					
					{tagWrap:"div",$id$:"check"},
					{tagOpen:"input",
						type:"checkbox",
						$id$:"wrapOpenCheck",
						$flag$:(this.wrapOpenCheck)?"checked":"",
						click:$this$.check},
					"wrapOpenHTML<BR>",
					{tagOpen:"input",
						type:"checkbox",
						$id$:"objectOpenCheck",
						$flag$:(this.objectOpenCheck)?"checked":"",
						click:$this$.check},
					"objectOpenHTML<BR>",
					{tagOpen:"input",
						type:"checkbox",
						$id$:"bodyOpenCheck",
						$flag$:(this.bodyOpenCheck)?"checked":"",
						click:$this$.check},
					"bodyOpenHTML<BR>",
					{tagOpen:"input",
						type:"checkbox",
						$id$:"contentOpenCheck",
						$flag$:(this.contentOpenCheck)?"checked":"",
						click:$this$.check},
					"conentOpenHTML<BR>",
					{tagOpen:"input",
						type:"checkbox",
						$id$:"contentCloseCheck",
						$flag$:(this.contentCloseCheck)?"checked":"",
						click:$this$.check},
					"conentCloseHTML<BR>",
					{tagOpen:"input",
						type:"checkbox",
						$id$:"bodyCloseCheck",
						$flag$:(this.bodyCloseCheck)?"checked":"",
						click:$this$.check},
					"bodyCloseHTML<BR>",
					{tagOpen:"input",
						type:"checkbox",
						$id$:"objectCloseCheck",
						$flag$:(this.objectCloseCheck)?"checked":"",
						click:$this$.check},
					"objectCloseHTML<BR>",
					{tagOpen:"input",
						type:"checkbox",
						$id$:"wrapCloseCheck",
						$flag$:(this.wrapCloseCheck)?"checked":"",
						click:$this$.check},
					"wrapCloseHTML<BR>",
				]
			];
		}

		this.contentCloseHTML=function(param,$this$)
		{
			return [
				(this.superClass!==$this$.superClass || this.contentCloseCheck)?{
					style:"width:auto;",
					tagName:"div",
					$id$:"contentClose",
					className:(this.superClass===$this$.superClass)?"view_class":"view_view_class",
					children:["contentCloseHTML Class: "+$this$+" Object: "+this]
				}:null
			];
		}

		this.bodyCloseHTML=function(param,$this$)
		{
			return [
				(this.superClass!==$this$.superClass || this.bodyCloseCheck)?{
					style:"width:auto;",
					tagName:"div",
					$id$:"bodyClose",
					className:(this.superClass===$this$.superClass)?"view_class":"view_view_class",
					children:["bodyCloseHTML Class: "+$this$+" Object: "+this]
				}:null
			];
		}
			
		this.objectCloseHTML=function(param,$this$)
		{
			return [
				(this.superClass!==$this$.superClass || this.objectCloseCheck)?{
					style:"width:auto;",
					tagName:"div",
					$id$:"objectClose",
					className:(this.superClass===$this$.superClass)?"view_class":"view_view_class",
					children:["objectCloseHTML Class: "+$this$+" Object: "+this]
				}:null
			];
		}

		this.wrapCloseHTML=function(param,$this$)
		{
			return [
				(this.superClass!==$this$.superClass || this.wrapCloseCheck)?{
					style:"width:auto;",
					tagName:"div",
					$id$:"wrapClose",
					className:(this.superClass===$this$.superClass)?"view_class":"view_view_class",
					children:["wrapCloseHTML Class: "+$this$+" Object: "+this]
				}:null
			];
		}

	})

	app.newObject("view.view")
	

CSS:


	.app-view_class, .app-check
	{
		border:1px solid blue;
		padding:5px;
		margin:5px;
	}
	
	.app-view_view_class
	{
		border:1px solid red;
		padding:5px;
		margin:5px;
	}

	.app-wrapOpen
	{
		padding:5px;
		margin:5px;
	}

	.app-objectOpen
	{
		padding:5px;
		margin:5px;
	}
	
	.app-bodyOpen
	{
		padding:5px;
		margin:5px;
	}
		
	.app-contentOpen
	{
		padding:5px;
		margin:5px;
	}

	.app-contentClose
	{
		padding:5px;
		margin:5px;
	}

	.app-bodyClose
	{
		padding:5px;
		margin:5px;
	}
		
	.app-objectClose
	{
		padding:5px;
		margin:5px;
	}

	.app-wrapClose
	{
		padding:5px;
		margin:5px;
	}

	.app-view-view
	{
		border:1px solid black;
		padding:5px;
		margin:5px;
	}
	
	.app-view-view .app-content
	{
		border:1px solid #cccccc;
		padding:5px;
		margin:5px;
	}