Direkt zum Hauptinhalt

Einen Bildschirm reagieren lassen

Ziel​

Einen gezeichneten Bildschirm etwas tun lassen: eine Überschrift, die den Namen zeigt, den jemand eingetippt hat, ein Bereich, der erscheint, wenn ein Kästchen angehakt wird, eine Schaltfläche „Speichern“, die erst aktiv wird, wenn das Formular ausgefüllt ist.

Nichts davon ist ein Bild, und nichts davon ist Code, den Sie in eine Datei schreiben. Es ist Zustand – die Handvoll Dinge, die sich ändern, während jemand den Bildschirm verwendet – und es sind Bindungen, einzeilige Ausdrücke, die ihn lesen.

Schritt 1 – Dem Bildschirm einen Zustand geben​

  1. Öffnen Sie den Bildschirm im Designer (Bildschirme → einen auswählen → Entwurf).
  2. Klicken Sie auf den Bildschirmrahmen selbst – das äußerste Feld – und öffnen Sie die Registerkarte Bildschirm im Inspektor rechts.
  3. Drücken Sie unter Bildschirmzustand auf Zustandsfeld hinzufügen.
  4. Geben Sie einen Namen ein – etwa requester – und einen Startwert.

Der Startwert ist ein Ausdruck, kein eingetippter Wert, daher beginnt ein leeres Feld als "" (zwei Anführungszeichen), ein Kontrollkästchen als false und ein Zähler als 0. Es ist dieselbe Sprache wie alles andere auf diesem Bildschirm, deshalb gibt es nur eine Sache zu lernen.

Fügen Sie so viele hinzu, wie der Bildschirm braucht. Die meisten Bildschirme brauchen zwei oder drei.

Warum der Zustand zum Bildschirm gehört

Weil zwei Steuerelemente dasselbe Feld lesen. Gehörte der Zustand zu dem Feld, von dem aus Sie ihn zufällig hinzugefügt haben, würde das Löschen dieses Feldes das Zustandsfeld mitnehmen – und alles andere, was es liest, würde stillschweigend aufhören zu funktionieren.

Schritt 2 – Eine Eigenschaft binden​

  1. Wählen Sie ein beliebiges Objekt auf der Zeichenfläche aus.
  2. Wählen Sie auf der Registerkarte Bildschirm unter Bindungen eine Eigenschaft aus Eigenschaft binden aus.
  3. Ein Editor mit einem Beispiel darin erscheint. Ersetzen Sie es durch Ihren Ausdruck.

Vier Eigenschaften lassen sich binden:

EigenschaftSteuertBei
Textwas es sagt – die Wörter einer Überschrift, die Beschriftung einer Schaltfläche, den Platzhalter eines Feldesallem
Angezeigtob es überhaupt auf dem Bildschirm istallem
Aktiviertob ein Steuerelement verwendet werden darfSteuerelementen
Wertwas ein Steuerelement enthältSteuerelementen

Alles andere an einem Objekt – wo es ist, wie groß, welche Farbe – haben Sie gezeichnet, und Zeichnen ist der bessere Weg, all das auszudrücken.

Beispiele, die echte Arbeit leisten:

state.requester the Text of a heading
"Hello, " + state.requester the same, with words around it
state.showDetails the Shown of a panel
!state.showDetails the Shown of the line that says it is empty
state.requester != "" the Enabled of a Save button
screen.width > 700 the Shown of something a narrow window has no room for

Der Editor ist der BS-Lang-Editor der Plattform, er unterstreicht also, was er nicht versteht, und bietet während der Eingabe Vervollständigungen an. Ist eine Unterstreichung da, fahren Sie mit der Maus darüber, um zu lesen, warum.

Schritt 3 – Ein Steuerelement zurückschreiben lassen​

Binden Sie den Wert eines Textfelds an state.requester, und Tippen darin setzt state.requester. Alles andere, was dieses Feld liest, folgt sofort – die Begrüßung, die Schaltfläche Speichern, alles.

Das ist alles, was einen Bildschirm lebendig wirken lässt, und es braucht keinen Handler.

Eine Regel: Zurückgeschrieben wird nur, wenn der Wert ein einfacher Zustandspfad ist – state.requester oder state.form.name. Ist er berechnet (state.first + " " + state.last), zeigt das Steuerelement den Wert an und ist schreibgeschützt, denn es gibt keinen Weg, von dem, was jemand eingetippt hat, auf die beiden Felder zurückzurechnen, aus denen er stammt.

Schritt 4 – Etwas passieren lassen, wenn eine Schaltfläche gedrückt wird​

  1. Wählen Sie die Schaltfläche aus.
  2. Wählen Sie unter Wenn dies geschieht aus Ereignis behandeln den Eintrag Gedrückt.
  3. Schreiben Sie, was passieren soll – eine Anweisung pro Zeile:
notify("Ticket raised for " + getState("requester"));
setState("requester", "");
setState("showDetails", false);

Was ein Handler aufrufen kann:

AufrufTut
setState("name", value)ändert den Zustand des Bildschirms – alles, was ihn liest, folgt
getState("name")liest ihn zurück, sodass Sie mit dem Vorhandenen rechnen können
loadRecords("table", "field")lädt Zeilen aus einer Tabelle in ein Zustandsfeld – siehe unten
getRecord("table", id, "field")lädt einen Datensatz anhand seiner ID
createRecord("table", { … }, "field")speichert einen neuen Datensatz; das dritte Argument ist optional
updateRecord("table", id, { … })ändert die genannten Felder eines Datensatzes
deleteRecord("table", id)löscht einen Datensatz
callApi("GET", "psl/v1/overview", { … }, "field")fragt eine Custom API und behält ihre Antwort — siehe Kennzahlen aus einer Custom API
notify("…") / notifyError("…")informiert die Person, die den Bildschirm verwendet
showModal("Card") / closeModal()zeigt eine Overlay-Karte über dem Bildschirm – siehe Schritt 5
openStartDrawer("Card") / closeStartDrawer()schiebt eine von der Anfangskante herein
openEndDrawer("Card") / closeEndDrawer()und von der Endkante
openDropdown("Card") / closeDropdown()öffnet eine neben dem, was gedrückt wurde
setVisualState("name")versetzt das nächstgelegene Objekt oberhalb dieses Handlers mit einem gezeichneten Zustand in diesen; "" kehrt zu Normal zurück – siehe Einen Entwurf mit Komponenten wiederverwenden
openUrl("…", "newTab")ruft eine Webadresse auf; lassen Sie das zweite Argument weg, um in diesem Fenster zu bleiben
navigate("Screen")wechselt zu einem anderen Bildschirm dieser App – über den Namen auf seinem Rahmen
reloadSurfaces()zeigt jede eingebettete Tabelle und jedes eingebettete Formular auf diesem Bildschirm mit frischen Daten neu an

Ein Handler ist ein kleines Programm, kein Ausdruck. Er darf Dinge ändern – genau dafür ist er da – und kann so viele Zeilen haben, wie er braucht. Das ist der Unterschied zu einer Bindung, die nur liest.

Die anderen Ereignisse sind da, wenn Sie sie brauchen: Doppelt gedrückt, Wert geändert (bei einem Steuerelement), Erhält Fokus, Verliert Fokus, Mauszeiger kommt, Mauszeiger geht und – auf dem Bildschirmrahmen selbst – Bildschirm wird geöffnet, das einmal ausgeführt wird, nachdem der Zustand existiert.

Um nur das Aussehen zu ändern, zeichnen Sie einen Zustand

Ein Handler, der nur etwas umfärbt, kostet bei jeder Mausbewegung Arbeit. Ein gezeichneter Zustand kostet gar nichts, denn der Browser erledigt ihn. Siehe Einen Entwurf mit Komponenten wiederverwenden.

Zu einem anderen Bildschirm der App wechseln​

Eine App enthält mehrere Bildschirme, und navigate wechselt zwischen ihnen:

navigate("Details");
navigate("Details", { id: getState("chosen") });

Der Name ist der Name auf dem Rahmen des Bildschirms, genau so, wie Sie ihn dort eingetippt haben – benennen Sie den Rahmen um, und jedes navigate, das den alten Namen nennt, funktioniert nicht mehr; der Bildschirm sagt Ihnen das beim Drücken, statt stillschweigend zu scheitern.

Was den Wechsel übersteht und was nicht. Der Bildschirm, den Sie verlassen, wird geschlossen: Sein Zustand ist weg, sodass Sie bei der Rückkehr einen frischen bekommen – ein halb ausgefülltes Formular soll nicht noch halb ausgefüllt sein, und ein Bildschirm, der beim Aufruf Zeilen geladen hat, lädt sie erneut. Mit reist, was Sie übergeben: Das zweite Argument kommt als screen.params an, sodass screen.params.id auf dem nächsten Bildschirm liest, was Sie gesendet haben.

Es heißt immer screen.params. Ein kürzeres params gibt es nicht, und der Code-Editor unterstreicht es.

Die Adressleiste folgt Ihnen. Jeder Bildschirm hat eine eigene URL, sodass die Zurück-Schaltfläche des Browsers zum vorherigen Bildschirm führt, ein Neuladen zum selben zurückkehrt und ein kopierter Link dort öffnet. Übergebene Werte reisen auf diesem Weg nicht mit – wer über Zurück, Neuladen oder einen eingefügten Link ankommt, öffnet den Bildschirm ohne screen.params –, behandeln Sie sie also als Übergabe zwischen zwei Bildschirmen und nicht als etwas, das ein Link tragen kann.

Datensätze lesen und schreiben​

Fünf Aufrufe, und zusammen machen sie aus einer Zeichnung eine Anwendung.

Eine Liste lesen:

loadRecords("par_ticket", "tickets");
loadRecords("par_ticket", "tickets", 20);
loadRecords("par_ticket", "tickets", { top: 20, where: { par_status: "Open" }, orderBy: "par_name" });

Die Zeilen landen im genannten Zustandsfeld, und alles andere auf dem Bildschirm weiß bereits, was damit zu tun ist – eine Tabelle wiederholt sich über state.tickets, eine Beschriftung liest state.tickets.length(). Siehe Eine Zeile zeichnen, eine pro Datensatz erhalten.

Das dritte Argument ist entweder wie viele höchstens oder die ganze Frage: top, where, orderBy und descending. where vergleicht nur auf Gleichheit, und jedes Paar, das Sie schreiben, muss zutreffen. Wenn Sie mehr brauchen – einen Bereich, „enthält“, ein oder –, bauen Sie mit dem Abfragedesigner eine Ansicht und zeichnen Sie den Bildschirm dagegen, statt es hier in eine Zeile zu zwängen.

Einen lesen:

getRecord("par_ticket", screen.params.id, "ticket");

Das ist das Gegenstück zu navigate("Details", { id: row.id }) – der Listenbildschirm übergibt die ID, und der Detailbildschirm holt den Datensatz dahinter. Gibt es diesen Datensatz nicht mehr, bleibt das Feld, wie es war, statt geleert zu werden, sodass die Bindungen darunter weiter funktionieren.

Schreiben:

createRecord("par_ticket", { par_name: getState("title"), par_status: "Open" });
createRecord("par_ticket", { par_name: getState("title") }, "created");
updateRecord("par_ticket", getState("ticket").id, { par_status: "Closed" });
deleteRecord("par_ticket", getState("ticket").id);

Das dritte Argument von createRecord ist optional und oft lohnend: Die Plattform antwortet mit dem Datensatz, den sie gespeichert hat, samt ID, sodass getState("created").id der Weg ist, wie der Bildschirm anschließend öffnet oder aktualisiert, was er gerade erstellt hat. Ohne es gibt es keine Möglichkeit, diese ID zu erfahren.

Die Feldnamen sind die logischen Namen der Spalten der Tabelle – par_name, nicht Name –, dieselben, die der Tabellendesigner zeigt.

Sagen Sie danach etwas

Nichts teilt der Person am Bildschirm mit, dass ein Schreibvorgang funktioniert hat, also sagen Sie es selbst: createRecord(…); notify("Ticket raised");. Lehnt die Plattform den Schreibvorgang ab – ein Pflichtfeld, eine Berechtigung –, zeigt der Bildschirm den Grund, den sie angegeben hat; deshalb lohnt es sich, die Meldung zu lesen, statt sie zu ersetzen. Der Rest dieses Klicks läuft dann nicht weiter, sodass ein notify oder navigate nach dem Schreiben nur geschieht, wenn es funktioniert hat.

Was ein Bildschirm tun darf, wird auf dem Server entschieden

Jeder dieser Aufrufe wird bei jedem Aufruf gegen die Berechtigungen derjenigen Person geprüft, die die App verwendet. Eine Schaltfläche „Löschen“ auszublenden, blendet eine Schaltfläche aus; es verhindert nichts.

Um jemanden auf eine Seite zu schicken, zeichnen Sie einen Link

openUrl ist für den Fall gedacht, dass der Bildschirm entscheidet, wohin es geht – nach dem Speichern oder abhängig davon, was ausgewählt wurde. Wenn das Ziel einfach feststeht, zeichnen Sie stattdessen einen Link: Mittelklick, Rechtsklick → In neuem Tab öffnen und die Linkliste eines Screenreaders funktionieren alle bei einem echten Link und bei nichts anderem. Siehe Eine Studio-App zeichnen.

Kennzahlen aus einer Custom API​

Eine Kennzahl — die Buchungen von heute, der Umsatz dieses Monats — ist ein Zeitraum und eine Summe, oft über mehrere Tabellen, und danach kann loadRecords nicht fragen. Berechnen Sie sie in einer Custom API und rufen Sie diese vom Bildschirm aus auf:

callApi("GET", "psl/v1/overview", { date: "2026-10-06" }, "figures");

Die Adresse ist die der API selbst unterhalb der Umgebung: ihr Herausgeberpräfix, ihre Version und ihre Route. Bei GET gehen die Eingaben als Abfragezeichenfolge mit, bei POST und den anderen als Body. Die Antwort landet im genannten Zustandsfeld, sodass ein an state.figures.bookingsToday gebundener Text sie zeigt. Die API läuft mit den Berechtigungen dessen, der den Bildschirm benutzt.

Nicht auf einem Portal

Eine Portalseite liest die Tabellen, die ihr Portal auflistet, und nennt nie eine API; callApi zeigt dort eine Meldung statt einer Antwort.

Wenn das Feld zu klein ist: die Codeseite​

Eine Bindung ist eine Zeile und gehört neben das, was sie steuert. Ein Handler wächst – und nach dem dritten if ist der kleine Editor im Bereich ein Briefschlitz.

Wählen Sie zuerst das Objekt aus und drücken Sie dann in der Symbolleiste Code schreiben (die Schaltfläche </>). Der Designer wird verdeckt – die Seite drumherum bleibt – von einer Liste alles Skriptbaren an diesem Objekt an der Seite und einem Editor mit Platz zum Schreiben. Die Liste enthält seine Bindungen, seine Handler, die Zustandsfelder des Bildschirms und die eigenen Eigenschaften einer Komponente. Auch noch nicht geschriebene werden aufgeführt – die schnellste Antwort auf „Was könnte ich hier eintragen?“.

Die Liste zeigt, welche davon geschrieben sind, sodass Sie keinen öffnen müssen, um es herauszufinden:

Neben dem NamenBedeutet
Ein grüner Punkt, Name fettGeschrieben, und es ergibt Sinn
Ein roter Punkt, Name fettGeschrieben, und es enthält einen Fehler – öffnen Sie es, und der Editor unterstreicht die Stelle
Ein hohler Punkt, Name abgeblendetNoch nichts geschrieben

Solange die Codeseite geöffnet ist, gehört die Tastatur dem Editor. Wer t tippt, tippt ein t; es greift nicht nach dem Textwerkzeug hinter der Seite.

Um zurückzukehren, drücken Sie Entwurf – dieselbe Schaltfläche, die Sie aus einer Vorschau zurückbringt, an derselben Stelle oben auf der Seite. Die Zeichnung ist genau so, wie Sie sie verlassen haben: dieselbe Auswahl, derselbe Zoom. Und es ist in beiden Fällen dasselbe Dokument, sodass ein hier geschriebener Handler dort im Bereich erscheint.

Wenn beim Drücken nichts passiert, sagt eine Meldung, warum, und es gibt nur drei Gründe:

Die MeldungWas zu tun ist
Nichts ist ausgewählt – oder mehr als ein ObjektWählen Sie genau ein Objekt aus
Code wird an der Komponente selbst geschriebenSie haben eine Kopie (eine Instanz) oder eine Variante ausgewählt. Rechtsklick → Zur Hauptkomponente wechseln und schreiben Sie ihn dort – jede Kopie bekommt ihn
Dieses Objekt ist Teil der Grafik des BildschirmsGeben Sie zuerst auf der Registerkarte Bildschirm an, was es ist – eine Schaltfläche, ein Textfeld –, dann hat es Handler, die man schreiben kann

Eine Komponente wird an ihrer Hauptkopie geschrieben. Wählen Sie den Rahmen aus, aus dem die Komponente besteht – nicht eine Kopie davon auf einem Bildschirm –, und die Liste bietet Gedrückt und die übrigen an, genau wie bei allem anderen. Dort gehört das Verhalten einer Komponente hin: einmal schreiben, und jede Kopie auf jedem Bildschirm tut es.

Schritt 5 – Vorher nachfragen, in einem Modal, einem Dropdown oder einer Schublade​

Eine Overlay-Karte ist ein Stück Bildschirm, das erst da ist, wenn ein Handler es anzeigt.

  1. Zeichnen Sie ihren Inhalt einmal, als Komponente. Eine Karte mit einer Frage und zwei Schaltflächen ist eine Komponente wie jede andere – siehe Einen Entwurf mit Komponenten wiederverwenden –, sodass dieselbe Bestätigung auf jedem Bildschirm verwendet werden kann, der eine braucht. Zeichnen Sie sie neben Ihren Bildschirm, wo Platz ist.

  2. Wählen Sie die Komponente aus und setzen Sie auf der Registerkarte Grafik das Häkchen bei Eine Overlay-Karte. Das ist die ganze Einrichtung: Sie wird nicht mehr auf dem Bildschirm gezeichnet und ist ab jetzt etwas, das ein Handler anzeigen kann.

  3. Zeigen Sie sie aus einem Handler an, über den eigenen Namen der Komponente:

    AufrufWo sie erscheintGeeignet für
    showModal("Confirm card")zentriert über dem Bildschirm, mit abgedunkeltem Hintergrundeine Frage, die beantwortet werden muss, bevor irgendetwas anderes geschieht
    openDropdown("Menu card")an dem Element, das gedrückt wurdeein kleines Menü, einen Hinweis, ein kurzes Formular
    openStartDrawer("Filters card")in voller Höhe, von der Anfangskante hereingleitendFilter, ein Menü in einem schmalen Fenster
    openEndDrawer("Details card")in voller Höhe, von der Endkanteeinen Detailbereich
  4. Schließen Sie sie mit closeModal(), closeDropdown(), closeStartDrawer() oder closeEndDrawer() – etwa von einer Schaltfläche darin aus. Eine Schublade hat keine eigene Schließen-Schaltfläche: Zeichnen Sie eine in die Karte, so wie es die Menüs der Beispiele tun. Escape und ein Klick neben die Schublade schließen sie trotzdem.

Eine Karte, die beantwortet werden muss​

Unter dem Häkchen Eine Overlay-Karte gibt es ein zweites: Muss beantwortet werden. Ist es gesetzt, funktionieren ein Klick außerhalb der Karte, die Escape-Taste und die Schließen-Schaltfläche nicht mehr, solange sie geöffnet ist – und die Schließen-Schaltfläche wird gar nicht angezeigt, denn ein Steuerelement, das sichtbar da ist und nichts tut, wirkt auf jeden, der es zweimal drückt, wie eine eingefrorene Seite.

Lassen Sie es aus, es sei denn, die Karte fragt etwas, das sich durch Weggehen nicht beantworten lässt. Ein Overlay, das jemand versehentlich geöffnet hat, sollte sich so schließen, wie es sich geöffnet hat; die eine Art, die das nicht darf, ist die, die dazu da ist, eine Antwort zu bekommen – „Diese vier Datensätze löschen?“, „Dieser Datensatz wurde von jemand anderem geändert, welche Fassung behalten?“ –, bei der ein Klick auf den Hintergrund keine Antwort ist und sich doch wie eine liest.

Zeichnen Sie Ihren eigenen Ausweg. Eine verpflichtende Karte verweigert jedes Schließen, das die Plattform bereitstellt, braucht also eine eigene Schaltfläche, die closeModal(), closeStartDrawer() oder closeEndDrawer() ausführt. Setzen Sie sie an den Anfang und heben Sie sie nicht hervor, so wie ein Abbrechen neben einem Löschen steht.

Ein Dropdown ignoriert es. Ein Menü, das sich nicht durch Wegklicken schließen lässt, hat die Seite gefangen, und ein Dropdown ist nie der Ort, an dem eine Frage gestellt wird.

Ein Dropdown öffnet sich an dem Element, das den Handler ausgeführt hat. Es gibt nichts zu wählen: Setzen Sie openDropdown("Menu card") auf die Schaltfläche, und das Menü erscheint neben dieser Schaltfläche.

Wo genau daran, können Sie angeben – openDropdown("Menu card", "bottom-end"):

PlatzierungWo die Karte hinkommt
"bottom" (Standard)unter die Schaltfläche, darauf zentriert
"bottom-start" / "bottom-end"darunter, bündig mit ihrer vorderen / hinteren Kante
"top", "top-start", "top-end"darüber – für ein Steuerelement nahe am unteren Rand eines Bildschirms

end, nicht right. Eine mit bottom-end geöffnete Karte hängt im Deutschen an der rechten Kante der Schaltfläche und im Persischen und Arabischen an ihrer linken, und das ist dieselbe Regel, der die Schubladen folgen: Ein Skript setzt das Menü in jeder Sprache auf die richtige Seite. "bottom-right" zu schreiben, ergäbe einen Bildschirm, der im Persischen verkehrt herum ist, ohne dass irgendetwas es sagt – deshalb ist es keine Platzierung, und ein Handler, der eine verlangt, bekommt das gesagt.

Sie äußern einen Wunsch, kein Versprechen: Ist unten kein Platz, öffnet sich das Menü trotzdem oben. Ein Menü, das über den Bildschirm hinausläuft, ist schlechter als ein Menü auf der anderen Seite.

Wie breit es ist, hängt davon ab, wie breit Sie es gezeichnet haben. Die eigene Breite der Karte ist die Breite der Schublade und des Modals – machen Sie die Karte also so groß, wie der Bereich sein soll.

Von jeder Art gibt es eine, und das Anzeigen einer zweiten Karte ersetzt die erste. Ein Bildschirm kann nur ein Modal gleichzeitig geöffnet haben, deshalb gibt es nichts zu deklarieren: Die Container sind immer da, und Ihr Handler sagt, was in einen davon kommt.

Die Kante einer Schublade folgt der Sprache, nicht der Zeichnung. Anfang ist links für jemanden, der Deutsch liest, und rechts für jemanden, der Persisch oder Arabisch liest – der ganze Bildschirm wird gespiegelt, denn in einer App ist das, was Sie gezeichnet haben, die Bedienoberfläche.

Esc, der Hintergrund und ein Klick außerhalb schließen ein Overlay, und der Fokus kehrt zu dem zurück, was es geöffnet hat. Nichts davon müssen Sie einstellen.

Schritt 6 – In der Vorschau ansehen​

Drücken Sie Vorschau. Die Vorschau ist die echte Laufzeit – dieselbe Komponente, die die Shell einbindet, keine Annäherung –, sodass Sie sehen, was jemand sieht, der die App verwendet.

Tippen Sie in die Felder. Sehen Sie zu, wie der Rest des Bildschirms folgt.

Regeln, die man kennen sollte​

Eine Bindung liest nur. Sie wird jedes Mal neu ausgeführt, wenn sich das Gelesene ändert, sodass eine Bindung, die etwas änderte, sich ständig selbst neu starten würde. Der Designer lehnt eine solche beim Speichern ab und nennt Objekt und Eigenschaft – alles, was etwas ändert, gehört in einen Handler.

„Angezeigt“ entfernt, es blendet nicht nur aus. Ein Element, dessen Angezeigt falsch ist, ist gar nicht auf der Seite: Nichts springt per Tab hinein, kein Screenreader sagt es an, und Strg+F findet es nicht. Das ist fast immer das, was Sie gemeint haben.

Nichts davon ist Sicherheit. Eine ausgeblendete Schaltfläche ist eine ausgeblendete Schaltfläche. Was eine Person tatsächlich tun darf, wird jedes Mal auf dem Server entschieden, gleich was der Bildschirm zeigt.

Was eine Bindung heute sehen kann​

NameIst
stateder eigene Zustand des Bildschirms, aus Schritt 1
screenscreen.width und screen.height – die Fläche, sodass ein Bildschirm auf ein schmales Fenster reagieren kann – und screen.name, der Bildschirm, auf dem Sie sind, sodass eine auf jedem Bildschirm platzierte Leiste ihre eigene Seite markieren kann
uiui.theme (light oder dark), ui.locale (en, fa, ar) und ui.dir (ltr oder rtl) – die eigenen Einstellungen des Lesers
userwer angemeldet ist: user.name, user.email und user.photo (leer, wenn es kein Foto gibt – binden Sie das Shown eines Bildes also an user.photo != "") – genug für eine Begrüßung oder eine obere Leiste, und bewusst nicht die Rollen der Person
screen.paramswas der Bildschirm, der Sie hierher geschickt hat, übergeben hat – navigate("Details", { id })

Datensätze kommen über einen Handler dorthin, nicht über einen eigenen Namen. loadRecords und getRecord legen sie im eigenen Zustand des Bildschirms ab, sodass eine Bindung state.tickets liest wie alles andere – es gibt keinen zweiten Ort, an dem man suchen müsste. Was es wirklich noch nicht gibt, sind die gespeicherten Ansichten der Plattform: Ein Bildschirm nennt eine Tabelle und ein where, keine Ansicht.

Was eine Bindung berechnen kann​

Eine Bindung ist ein Ausdruck, kann also keine Schleife durchlaufen und nicht setState aufrufen. Einige kleine Funktionen decken ab, was eine Beschriftung über Arithmetik hinaus meist braucht:

FunktionLiefert
text(value)den Wert als Wörter, sodass eine Zahl in einem Satz stehen kann – "of " + text(state.total)
num(value)die Wörter als Zahl – das, was ein Dropdown zurückgibt, bereit zum Rechnen; 0, wenn es keine ist
first(list, { field: value, … })die erste Zeile einer geladenen Liste, deren Felder diese Werte enthalten, oder null – first(state.budgets, { par_department: state.department, par_category: state.category })
format(value, "integer" | "number" | "percent")eine Zahl so, wie Ihre Sprache sie schreibt – format(174500, "integer") ist 174,500 im Englischen und persische Ziffern im Persischen
translate({ en: "…", fa: "…", ar: "…" })die Wörter für die Sprache des Lesers, mit Englisch als Rückfall – siehe Zwei Sprachen

first ist der Weg, wie eine Beschriftung einer Auswahl zu der Zeile folgt, die sie nennt. Laden Sie die Tabelle einmal, bei Bildschirm wird geöffnet; dann folgt "Available: £" + format(first(state.budgets, { … }).par_remainingbudget, "integer") zwei Dropdowns, wohin sie auch gehen, ohne Handler. Eine geladene Zeile trägt eine Auswahlspalte als ihre Beschriftung, und ein Dropdown gibt die Beschriftung zurück, die es angeboten hat, sodass beide übereinstimmen. Sichern Sie den Fall ab, dass nichts passt, mit einer Bedingung – first(…) == null ? "Choose a line" : … –, denn ein Feld von null zu lesen, lässt die Bindung scheitern, und && schützt davor nicht: Beide Seiten eines && werden immer ausgewertet.

Ein Bereich ist Aufgabe eines Handlers. first vergleicht Werte exakt; „das Band, dessen Minimum und Maximum diesen Betrag einschließen“ ist eine Schleife, und eine Schleife gehört in den Handler Wert geändert des Steuerelements, der das Gefundene für die Beschriftung in den Zustand schreibt. Das Beispiel studio-capital-planning in samples/solutions tut beides auf einem Bildschirm.

Zwei Sprachen auf einem Bildschirm​

Binden Sie den Text eines Textobjekts an translate(...), mit jeder Sprache neben dem Englischen:

translate({ en: "Opening times", fa: "ساعات کار" })

und geben Sie der Seite eine Schaltfläche, die umschaltet: if (ui.locale == "fa") { setLanguage("en"); } else { setLanguage("fa"); }. setLanguage ändert die Sprache der Plattform, nicht nur die des Bildschirms: Sie wird gespeichert, und im Persischen oder Arabischen wird die ganze Seite gespiegelt, denn jede Position, die ein Bildschirm zeichnet, ist Anfang und Ende statt links und rechts. ui.dir sagt, in welche Richtung gelesen wird, sodass ein Pfeil in die richtige Richtung zeigen kann.

Eine Sprache, die das Objekt nicht hat, fällt auf Englisch zurück, sodass eine halb übersetzte Seite auf Englisch zu lesen ist statt als Lücken. Das Beispiel portal-pages-and-navigation ist so geschrieben, jedes einzelne Wort.

Etwas, das von selbst geschieht: der Timer​

Geben Sie einem Objekt einen Handler Timer tickt und binden Sie sein Timer-Intervall (ms) – es führt diesen Handler alle so und so viele Millisekunden aus, solange das Objekt auf der Seite ist:

Timer interval (ms): state.held ? 0 : 5000
Timer ticks: setState("slide", (getState("slide") + 1) % 3);

Null oder nichts bedeutet angehalten – das Pausieren ist also Teil der Bindung, und ein Karussell, das stehen bleibt, während Sie darauf zeigen, setzt held in seinen Handlern Mauszeiger kommt und Mauszeiger geht. Werte unter 250 werden auf 250 angehoben. Ein ausgeblendetes Objekt tickt nicht. Das Karussell in der Komponentenbibliothek und auf der Startseite von portal-pages-and-navigation ist so gebaut.

Fehlerbehebung​

  • „Eine Bindung an … konnte nicht ausgeführt werden“ – der Ausdruck ist gültig, aber etwas, das er nennt, ist nicht da. Die häufigste Ursache ist ein Zustandsfeld, das anders geschrieben ist als in der Bindung: Prüfen Sie die Liste Bildschirmzustand des Bildschirmrahmens.
  • Das Feld lässt mich nicht hineintippen. – Sein Wert ist ein berechneter Ausdruck, daher ist es bewusst schreibgeschützt. Binden Sie es stattdessen an ein einfaches Zustandsfeld und berechnen Sie das andere woanders.
  • Beim Tippen passiert nichts. – Das Feld hat keine Bindung Wert. Ein Feld ohne Bindung behält, was eingetippt wird, und sagt es niemandem.
  • Die Schaltfläche Speichern wird nie aktiv. – Prüfen Sie ihren Ausdruck Aktiviert gegen einen leeren Wert: state.requester != "" ist erst wahr, wenn etwas eingetippt wurde.
  • Das Drücken der Schaltfläche bewirkt nichts. – Ein deaktiviertes Steuerelement empfängt gar kein Drücken, prüfen Sie also zuerst seine Bindung Aktiviert; prüfen Sie dann, ob der Handler auf Gedrückt liegt und nicht auf einem Ereignis, das hier nie ausgelöst wird (Bildschirm wird geöffnet gehört zum Bildschirmrahmen, Wert geändert zu einem Steuerelement).
  • „Ein Handler an … konnte nicht ausgeführt werden“ – der Handler ist gültiges BS Lang, aber etwas, das er nennt, ist nicht da. Die häufigste Ursache ist setState auf einem Feld, das der Bildschirm nie deklariert hat.
  • „createRecord("…") failed: …“ – die Plattform hat den Schreibvorgang abgelehnt, und was nach dem Doppelpunkt folgt, ist ihre eigene Begründung: ein Pflichtfeld ohne Inhalt, ein Wert, der keine der Auswahlmöglichkeiten ist, oder eine Berechtigung, die Sie nicht haben. Prüfen Sie zuerst die Feldnamen gegen den Tabellendesigner – ein falsch geschriebener logischer Name ist die häufigste Ursache.
  • Nichts wird geladen, und nichts beschwert sich. – Sie sind in der Vorschau, hinter der keine Umgebung steht. Die Datensatzaufrufe tun dort absichtlich nichts. Öffnen Sie die App aus der Shell, um echte Datensätze zu sehen.
  • showModal("…") bewirkt nichts. – Der Name muss genau dem Namen der Komponente entsprechen, und bei der Komponente muss Eine Overlay-Karte angehakt sein. Eine gelöschte oder umbenannte Karte hinterlässt Handler, die sie nennen, und diese tun stillschweigend nichts, statt den Bildschirm kaputtzumachen.
  • Die Karte erscheint auf dem Bildschirm statt in einem Modal. – Eine Overlay-Karte ist nicht angehakt. Bis dahin wird die Komponente dort gezeichnet, wo Sie sie hingesetzt haben, wie jede andere Komponente.
  • „Zwei Komponenten heißen beide …“ – eine Karte wird über den Namen ihrer Komponente angezeigt, also sind zwei mit demselben Namen eine Frage, die showModal nicht beantworten kann. Benennen Sie eine um.

Probieren Sie es aus​

Importieren Sie die Beispiellösung Ticket Triage. Sie ist diese Seite, gebaut: drei Zustandsfelder, durchgehend gebundene Eigenschaften, ein Zustand, den das Beispiel selbst benannt hat, ein Modal, das nachfragt, bevor es das Ticket anlegt, und ein Popover, das sich von seiner eigenen Schaltfläche aus öffnet.