Activate JS ist eine JQuery basierende Templating Engine.
Ein Control-Attribut besteht aus einem JSON-String, der ein oder mehrere Paare aus Control-Name und Control-Wert enthält {<control-name>: <control-value>, ...}. Control-Werte können von unterschiedlichem Typ sein:
Typ Control-Wert | Beispiel | Erklärung |
---|---|---|
Literal | 'some-value' | Die Zeichenkette wird so übernommen. Anwendungen sind die Definition von Template-Namen oder das Setzen von CSS-Literalen. |
Wert | true, false, 1, 2, 3 | Der Wert wird so übernommen. Anwendungen sind Parameter, For-Werte oder Bedingungen. |
Javascript-Expression | this.test == 1, !x | Der Javascript-Ausdruck wird ausgewertet und das Ergebnis übernommen. Es ist zu beachten, dass die Evaluierung vor dem Verarbeiten des Controls ausgeführt wird. Eventuell später erzeugte Werte können daher nicht zur Verfügung stehen. |
Javascript-Function | function() {this.test == 1} | Die Funktion wird erst dann evaluiert, wenn der Wert tatsächlich verwendet wird. Damit können voneinander abhängige Ausdrücke verwendet werden, wie etwa bedingte Färbung von Zeilen innerhalb eines For-Control. |
<div control="{apply: $.fn.Panel}"> <div>Header</div> <div>Content</div> </div>
Erklärung: Das Attribut "control" enthält JSON-Code, der ein oder mehrere Key-Value-Paare enthalten kann. Jeder Key ist einem Control aus $.controls zugeordnet. Im obigen Beispiel also der Key apply ruft $.controls.apply auf. This entspricht dabei dem JQuery-Element des Elements. Verwendet man die Bridge eines JQuery-Widgets, wie etwa $.fn.Panel, wird das JQuery-Widget instantiiert.
<div control="{template: 'some-panel', apply: $.fn.Panel}" style="margin-top: 10px;"> <div>Template Header</div> </div>
<div control="{applyTemplate: 'some-panel'}"> <div>Individual Content 1</div> </div>
<div control="{template: 'some-panel', apply: $.fn.Panel}" style="margin-top: 10px;"> <div>Panel Template</div> <div control="{insert: 'content'}"/> </div> <div control="{applyTemplate: 'some-panel'}"> <div control="{define: 'content'}">Individual Content 2</div> </div>
Erklärung: Das Element (div) mit dem Control applyTemplate wird durch das Template mit dem Namen "some-panel" ersetzt. Dabei werden alle Controls des Templates angewendet, zusätzlich zu den einfügenden Element.
<div control="{for: {begin: 0, end: 3, variable: 'index'}}"> <div control="{interpolate: true}">Count: {index}</div> </div>
<div control="{for: {list: this.someList, variable: 'element'}}"> <div control="{interpolate: true}">Element: {element}</div> </div>
<div control="{for: {list: this.someObject, variable: 'value'}}"> <div control="{interpolate: true}">Key: {index}, Value: {value}</div> </div>
<div control="{for: {begin: 0, end: 3, variable: 'x'}}"> <div control="{interpolate: true}">Iteration No. {x}</div> </div>
<form id="form"> <div control="{id: 'text'}">Some Text</div> </form>
Ergebnis: Das innere div-Element erhält das Attribut id="form:text".
Ein beliebter Kunstgriff ist, Teile der Page zunächst mit dem Style display oder visibility unsichtbar zu machen und erst nach fertiger Aktivierung anzuzeigen:
<div style="display: none;" control="{id: 'activate-test', after: {css: {display: 'block'"> ... </div> }}}
<div style="display: none;" control="{id: 'activate-test', after: {css: {display: 'block'"> ... </div> }}}
Erklärung: Es handelt sich um dasselbe Beispiel wie bei dem Control style, jedoch geht es hier um den Aspekt after. Das Control after enthält als Wert wieder eine Liste von Controls, die nach der Aktivierung der Children ausgeführt werden.
<div control="{applyTemplate: 'some-panel', set: {templateParam: 2}}"> <div control="{define: 'content'}">Individual Content 2</div> </div> <div control="{template: 'some-panel', apply: $.fn.Panel}" style="margin-top: 10px;"> <div control="{interpolate: true}">Panel Template, Parameter: {templateParam}</div> <div control="{insert: 'content'}"/> </div>
Erklärung: Der Parameter templateParam wird von der Einfügestelle applyTemplate an das Template selbst übergeben. Das heißt, jede Template-Instanz kann einen unterschiedlichen Wert erhalten.
<div control="{if: test == 2, css: {color: '#10a010'}}">Some Text</div>
Hinweis: Die If-Condition wird während des Parsens des Javascript-Code ausgeführt, was in vielen Fällen zu früh sein kann.
Um auf Ergebnisse anderer Controls zugreifen zu können, kann die Condition auch eine Funktion sein:
<div control="{if: function() {return this.test == 2}, css: {color: '#10a010'}}">Some Text</div>
<label control="{rendered: function() {this.type != 'input'}}">Input</label>
<div control="{ajax: {url: 'http://localhost/test', variable: 'data'}, interpolate: true}">{data}</div>
Erklärung: Es wird ein AJAX-Request durchgeführt und das Ergebnis in der Variable data gespeichert. Das nachfolgende Interpolation-Control fügt den Text in den Tag-Content ein.
Die möglichen AJAX-Control Parameter:
Parameter | Bedeutung |
---|---|
method | HTTP Method, die verwendet wird, wohl hauptsächlich GET oder POST |
URL | Die URL, die für den AJAX-Request benutzt wird |
data | Die Query/Post-Parameter für den AJAX-Request |
variable | Die Variable in der das Ergebnis gespeichert wird |
$.controls.myControl = function(next) { this.element.text("Hello World!"); next(); };
Hinweis: Ein Control hat immer den Parameter next, der in der Regel am Ende aufgerufen wird. Dieser sorgt dafür, dass die nachfolgenden Controls und damit auch untergeordnete Elemente aktiviert werden.
Bei mehreren Controls kann man die bequemere Variante mit QUuery extends verwenden:
$.controls.extend({ myControl: function(next) { this.element.text("Hello World!"); next(); }, myControl2: function(next) { this.element.text("Second Control!"); next(); } });
Im Aufruf des Controls wird this auf den aktuellen Context gesetzt.
Key | Beschreibung |
---|---|
element | Das aktuelle JQuery-Element in dem der Funktionsaufruf stattfindet. |
controls | Die aktuelle Control-Struktur, die gerade abgearbeitet wird. |
control | Der aktuelle Control-Entry, der gerade verarbeitet wird. Er besteht aus key (Name) und value (function). |
root | Zugriff auf dem Root-Context. Kann für Templates und andere globale Variablen verwendet werden. |
prefix | Das aktuelle Prefix des aktuellen Id-Attributs. Dies besteht aus den Id's der übergeordneten Elemente, getrennt durch Doppelpunkte. |
Der Context enthält auch eine Reihe von Funktionen, die für das Implementieren eines Controls nützlich sein können:
Funktion | Beschreibung |
---|---|
pop() | Holt das nächste Control aus der aktuellen Control Execution Chain. Das Control ist damit dauerhaft entfernt und wird nicht mehr durch den Aufruf von next() ausgeführt. |
activate(element, options) | Aktiviert die Controls an einem Element und deren Unterknoten. Normalerweise wird diese Funktion durch den Aufruf von next() automatisch ausgeführt. Programmatisch erzeugte Elemente, wie bei Iterationen, können einen expliziten Aufruf erfordern. |
interpolate(text) | Liefert den übergebenen Text, alle Variablen werden durch ihre Werte ersetzt. |
resolve(expression) | Liefert den Wert einer Variable zurück. |
warn(message) | Gibt eine Warnung auf der Konsole mit entsprechenden Kontext-Informationen und Aufrufstack aus, um Fehler leichter lokalisieren zu können. |
Warning: Die Grundfunktionen des Context sollten nicht überschrieben werden, weder durch User-Extends, noch durch Controls mit Variable- oder Set-Anweisung, da es sonst zu Fehlern kommen kann.