Objekte werden bei diesem UI nicht, wie in Javascript üblich, per "new" erstellt, sondern mit der Methode "app.newObject". Diese Methode verwaltet die "Prototype-Chain" aka "Super-Klassen" und erledigt noch einige andere Dinge, die mit einem einfachen "new" nicht mehr realisierbar sind. Klassen selber, sind keine Funktionen die per "prototype" vererbt werden, sondern ebenfalls Objekte die per "app.newClass" erzeugt werden.


	this.newClass=function(name,sup,classDef,param){...}
	app.newClass("name","superClass",function(param,app,superClass){
		this.classType="name"
	})
	app.newObject("name")
	

Namespaces

Die Angabe von "Namespaces" funktioniert hier etwas anders als dies im Allgemeinen gängig ist. Die Klassische Punkt-Notation dient hier zur Erstellung einer Javascript "Prototype-Chain". Wenn der Name "Namespace" Angaben machen soll, muss er in Eckige Klammern gesetzt werden (diese können entfallen, wenn die definierte Klasse eine Basisklasse sein soll, der Name also keine Punkte enthält).


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

	app.newClass("[base.part]","content",function(param,app,superClass){
		this.classType="[base.part]"
	})
	

Hier wurden also 2 Klassen erzeugt, deren Namen sich im Namespace "base" befinden. Enthält die Klasse "base" Methoden die in "base.part" zur Verfügung stehen sollen, kommt die klassiche Vererbung ins Spiel


	app.newClass("[base.basePart]","base",function(param,app,superClass){
		this.classType="[base.basePart]"
	})
	

Die Super-Klasse von "[base.basePart]" ist also "base". Hier setzen auch die erweiterten Möglichkeiten an. Es ist möglich eine komplette Kette von Superklassen anzugeben. Die "Namespace" Unterstützung erfolgt hierbei wieder mit eckigen Klammern. Es können gleiche Klassen mehrmals angegeben werden.

Die "Javascript-Notation" empfielt sich in diesem Fall, um Klarheit über die erzeugte "Prototype-Chain" zu erhalten, ansonsten sollte es ein ausagekräftiger Name sein, der die "Verhältnisse" wiederspiegelt (z.B. "[data.db]" und/oder "[data.rest]" etc.). Bindestriche und Unterstriche sollten niemals in Namens-Teilen benutzt werden, da die Style-Klassen-Namen, die automatisch aus den Klassen-Namen generiert werden, Bindestriche und Unterstriche verwenden um die Klassennamen in CSS Syntax kollisionsfrei darzustellen. Ein Klassenname wie "klassenname1[klassenname2.klassenname3]" wird z.B. zu der CSS Klasse: "app-klassenname1-klassenname2_klassenname3" für ein aus der Klasse erzeugtes Objekt.

Eine Weitere Möglichkeit, die obige Klassenverknüpfung zu erhalten, wäre natürlich "part" ebenfalls als eine "Basis"-Klasse zu definieren. Hier besteht allerdings die Gefahr, dass die Namen für mögliche "Basis"-Klassen irgendwann ausgehen und es zu Namens-Kollisionenn kommt. Im folgenden Beispiel ist diese Möglichkeit, wegen der Vollständigkeit, mit aufgeführt. Dies sollte aber nur mit Klassen gemacht werden, die auch allgemeine Funktionalität bereit stellen. Die Basisklassen dieses UI sind in dieser Art und Weise definiert und bilden eine grundlegende "Prototype-Chain" (sozusagen "einen Stamm"), an die weitere Klassen angeknüpft werden können (die Analogie zu "Ästen" bietet sich hier an).

Script:


	app.newClass("base","content",function(param,app,superClass){
		this.classType="base"
		this.objectOpenHTML=function(param,$this$)
		{
			if($this$.superClass===this.superClass)
			{
				return [{tagName:"div",children:["Object:"+this+" Type Chain:"+this.typeChain+" Style Class:"+this.styleClass]}];
			}
		}
	})
	
	app.newClass("[base.part]","base",function(param,app,superClass){
		this.classType="[base.part]"
		this.objectOpenHTML=function(param,$this$)
		{
			if($this$.superClass===this.superClass)
			{
				return [{tagName:"div",children:["Object:"+this+" Type Chain:"+this.typeChain+" Style Class:"+this.styleClass]}];
			}
		}
	})

	
	app.newClass("part","base",function(param,app,superClass){
		this.classType="part"
		this.objectOpenHTML=function(param,$this$)
		{
			if($this$.superClass===this.superClass)
			{
				return [{tagName:"div",children:["Object:"+this+" Type Chain:"+this.typeChain+" Style Class:"+this.styleClass]}];
			}
		}
	})
	
	app.newClass("base2","content",function(param,app,superClass){
		this.classType="base2"
		this.objectOpenHTML=function(param,$this$)
		{
			if($this$.superClass===this.superClass)
			{
				return [{tagName:"div",children:["Object:"+this+" Type Chain:"+this.typeChain+" Style Class:"+this.styleClass]}];
			}
		}
	})

	app.newClass("part2","base2",function(param,app,superClass){
		this.classType="part2"
		this.objectOpenHTML=function(param,$this$)
		{
			if($this$.superClass===this.superClass)
			{
				return [{tagName:"div",children:["Object:"+this+" Type Chain:"+this.typeChain+" Style Class:"+this.styleClass]}];
			}
		}
	})

	
	
	app.newClass("mashup","base.base2",function(param,app,superClass){
		this.classType="mashup"
		this.objectOpenHTML=function(param,$this$)
		{
			if($this$.superClass===this.superClass)
			{
				return [{tagName:"div",children:["Object:"+this+" Type Chain:"+this.typeChain+" Style Class:"+this.styleClass]}];
			}
		}
	})

	app.newClass("mashup2","base[base.part]base2",function(param,app,superClass){
		this.classType="mashup2"
		this.objectOpenHTML=function(param,$this$)
		{
			if($this$.superClass===this.superClass)
			{
				return [{tagName:"div",children:["Object:"+this+" Type Chain:"+this.typeChain+" Style Class:"+this.styleClass]}];
			}
		}
	})
	app.newObject("base")
	app.newObject("[base.part]")
	app.newObject("base.part")
	app.newObject("base2")
	app.newObject("mashup")
	app.newObject("mashup2")
	

Beispiel:

In dem obigen Beispiel werden aus den Klassen die entsprechenden Objekte erzeugt. "Type Chain" gibt die "Prototype-Chain" des Objektes wieder. "Style Class" sind die automatisch generierten CSS Klassen für das erzeugte Objekt. Der (wahlfreie) Prefix "app-" fehlt hier, da er erst beim Setzen der CSS-Klasse hinzugefügt wird.

Alias-Klassen

Um Tipparbeit zu sparen und Klassen in einer Klassen-Kette zusamenzufassen, dienen Alias-Klassen. Diese werden wie normale Klassen definiert, ihnen fehlt allerdings die Angabe der Klassen-Typs (this.classType). Alias-Klassen können beliebig benutzt werden, um neue Klassen zu erzeugen. Die CSS-Klassen für die abgeleiteten Objekte, werden aus den zusammengefassten Klassen und aus dem Namen der Aliasklasse erzeugt

In folgendem Beispiel ist die Erzeugung von Klassen mit "normalen" Klassen und Alias-Klassen gegenüber gestellt.

Skript:


	app.newClass("[demo.simpleClass]","content",function(param,app,superClass){
		this.classType="[demo.simpleClass]"
		this.objectOpenHTML=function(param,$this$)
		{
			if($this$===this.superClass || $this$.superClass===this.superClass)
			{
				return [{tagName:"div",children:["Object:"+this+" Type Chain:"+this.typeChain+"<BR> Style Class:"+this.styleClass]}];
			}
		}
		this.contentOpenHTML=function(param,$this$)
		{
			return [{tagName:"div",$id$:"div",children:["Class:"+$this$]}];
		}
	})
	
	app.newClass("aliasClass","[demo.simpleClass][demo.simpleClass][demo.simpleClass]",function(param,app,superClass){
		this.contentOpenHTML=function(param,$this$)
		{
			return [{tagName:"div",$id$:"div",children:["Class:"+$this$]}];
		}
	})
	
	
	app.newClass("usingAliasClass","[demo.simpleClass]aliasClass[demo.simpleClass]",function(param,app,superClass){
		this.contentOpenHTML=function(param,$this$)
		{
			return [{tagName:"div",$id$:"div",children:["Class:"+$this$]}];
		}
	})
	
	
	app.newClass("usingAliasClass2","[demo.simpleClass]aliasClass[demo.simpleClass]",function(param,app,superClass){
		this.classType="usingAliasClass2"
		this.contentOpenHTML=function(param,$this$)
		{
			return [{tagName:"div",$id$:"div",children:["Class:"+$this$]}];
		}
	})
	
	
	app.newClass("notAliasClass","[demo.simpleClass][demo.simpleClass][demo.simpleClass]",function(param,app,superClass){
		this.classType="notAliasClass"
		this.contentOpenHTML=function(param,$this$)
		{
			return [{tagName:"div",$id$:"div",children:["Class:"+$this$]}];
		}
	})
	
	
	app.newClass("usingNotAliasClass","[demo.simpleClass]notAliasClass[demo.simpleClass]",function(param,app,superClass){
		this.contentOpenHTML=function(param,$this$)
		{
			return [{tagName:"div",$id$:"div",children:["Class:"+$this$]}];
		}
	})
	
	
	app.newClass("usingNotAliasClass2","[demo.simpleClass]notAliasClass[demo.simpleClass]",function(param,app,superClass){
		this.classType="usingNotAliasClass2"
		this.contentOpenHTML=function(param,$this$)
		{
			return [{tagName:"div",$id$:"div",children:["Class:"+$this$]}];
		}
	})
	
	app.newObject("[demo.simpleClass]",{size:{height:"auto"}})
	
	app.newObject("aliasClass",{size:{height:"auto"}})
	app.newObject("notAliasClass",{size:{height:"auto"}})
	
	app.newObject("usingAliasClass",{size:{height:"auto"}})
	app.newObject("usingNotAliasClass",{size:{height:"auto"}})
	
	app.newObject("usingAliasClass2",{size:{height:"auto"}})
	app.newObject("usingNotAliasClass2",{size:{height:"auto"}})
	

Beispiel:

Komponenten-Klassen

Die dritte Möglichkeit Klassen zu definieren, sind Komponenten-Klassen. Diese Klassen haben keine Superklassen und werden in den Superklassen-Ketten anderer Klassen benutzt.

Skript:


	app.newClass("ol","content",function(param,app,superClass){
		this.classType="ol"
		this.contentOpenHTML=function(param,$this$)
		{
			return {tagOpen:"ol",$id$:"ul"};
		}
		this.contentCloseHTML=function(param,$this$)
		{
			return {tagClose:"ol"};
		}
	})
	
	app.newClass("li","",function(param,app,superClass){
		this.classType="li"
		this.contentOpenHTML=function(param,$this$)
		{
			return {tagName:"li",$id$:"li",children:[this.text||"Listitem"]};
		}
		this.setText=function(str)
		{
			getElement.call(this,"li").innerHTML=str||""
		}
	})
	
	var o=app.newObject("ol.li.li.li.ol.li",{size:{height:"auto"}})
	o["ol.li"].setText.call(o,"Item 1")
	o["ol.li.li"].setText.call(o,"Item 2")
	o["ol.li.li.li"].setText.call(o,"Item 3")
	o["ol.li.li.li.ol.li"].setText.call(o,"Item 3.1")
	

Beispiel: