Client-seitige Skripterstellung und Verarbeitung
Durchdacht programmierte Client-Skripts können die Zeit verringern, die Benutzer zum Ausfüllen eines Formulars benötigen.
Für eine korrekte clientseitige Verarbeitung muss das Formular zunächst geladen werden. Wird der Datensatz vor dem Laden des Formulars aktualisiert, kann das zu unerwarteten Ergebnissen führen, die bei der clientseitigen Verarbeitung nicht berücksichtigt werden.
- Deaktivieren der Listenbearbeitung für die Tabelle
- Erstellen passender Business Rules oder Zugriffssteuerungen für die Listenbearbeitung
- Erstellen von Datenrichtlinien
- Erstellen eines separaten Client-Skripts des Typs „onCellEdit“
Einschränken der Listenbearbeitung
Wenn Sie UI-Richtlinien oder Client-Skripts für Formularfelder erstellen, müssen Sie eine andere Methode verwenden, um sicherzustellen, dass die Daten in diesen Feldern in einer Liste ähnlich gesteuert werden.
- Deaktivieren der Listenbearbeitung für die Tabelle
- Erstellen passender Business Rules oder Zugriffssteuerungen für die Listenbearbeitung
- Erstellen von Datenrichtlinien
- Erstellen eines separaten Client-Skripts des Typs „onCellEdit“
Serversuchen auf ein Minimum reduzieren
Verwenden Sie wann immer möglich Client-Daten, um zeitaufwendige Serversuchen zu vermeiden.
Client-Skripts verwenden entweder Daten auf dem Client oder Daten, die vom Server abgerufen werden. Die wichtigsten Methoden zum Abrufen von Informationen vom Server sind „g_scratchpad“ und asynchrone Suchen des Typs „GlideAjax“.
Der Hauptunterschied zwischen beiden Methoden: „g_scratchpad“ wird einmalig beim Laden eines Formulars gesendet (Informationen werden vom Server an den Client gesendet), während „GlideAjax“ dynamisch ausgelöst wird, sobald der Client Informationen vom Server anfordert.
Serverdaten abrufen mit „g_scratchpad“
Das Objekt „g_scratchpad“ übergibt Informationen vom Server an den Client, beispielsweise wenn der Client Informationen benötigt, die im Formular nicht verfügbar sind.Angenommen ein Client-Skript muss auf das Feld „u_retrieve“ zugreifen, dieses Feld existiert aber im Formular nicht. Die Daten sind dann für das Client-Skript nicht verfügbar. Eine gängige Lösung für einen solchen Fall besteht darin, das Feld zwar im Formular zu platzieren, es jedoch per Client-Skript oder UI-Richtlinie permanent auszublenden. Diese Lösung mag sich schneller konfigurieren lassen, wird aber langsamer ausgeführt.
Wenn Sie bereits vor dem Laden des Formulars wissen, welche Informationen der Client vom Server benötigt, können Sie über eine beim Anzeigen ausgeführte Business Rule Eigenschaften des Typs „g_scratchpad“ erstellen. Die Informationen werden dann in diesen Eigenschaften hinterlegt. Das Objekt „g_scratchpad“ wird an den Client gesendet, sobald das Formular angefordert wird. Damit ist es für alle clientseitigen Skriptmethoden verfügbar. Dies ist eine sehr effiziente Möglichkeit, Informationen vom Server an den Client zu senden. Allerdings können Daten nur auf diese Weise geladen werden, während das Formular geladen wird. Die Business Rule kann nicht dynamisch ausgelöst werden. In solchen Fällen müssen Sie einen asynchronen Aufruf des Typs „GlideAjax“ verwenden.
- Den Wert der Systemeigenschaft „css.base.color“
- Ob der aktuelle Datensatz Anhänge enthält
- Den Namen des Vorgesetzten des Anrufers
g_scratchpad.css = gs.getProperty('css.base.color');
g_scratchpad.hasAttachments = current.hasAttachments();
g_scratchpad.managerName = current.caller_id.manager.getDisplayValue();// Check if the form has attachments
if (g_scratchpad.hasAttachments)
// do something interesting here
else
alert('You need to attach a form signed by ' + g_scratchpad.managerName);Serverdaten mit asynchronen Aufrufen des Typs „GlideAjax“ abrufen
Mit asynchronen Aufrufen des Typs „GlideAjax“ können Sie Informationen dynamisch vom Server anfordern.
//Alert if the assignment groups name matches the support group
function onChange(control, oldValue, newValue, isLoading) {
if (isLoading)
return;
var ga = new GlideAjax('ciCheck');
ga.addParam('sysparm_name', 'getCiSupportGroup');
ga.addParam('sysparm_ci', g_form.getValue('cmdb_ci'));
ga.addParam('sysparm_ag', g_form.getValue('assignment_group'));
ga.getXML(doAlert); // Always try to use asynchronous (getXML) calls rather than synchronous (getXMLWait)
}
// Callback function to process the response returned from the server
function doAlert(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
alert(answer);
}var ciCheck = Class.create();
ciCheck.prototype = Object.extendsObject(AbstractAjaxProcessor, {
getCiSupportGroup: function() {
var retVal = ''; // Return value
var ciID = this.getParameter('sysparm_ci');
var agID = this.getParameter('sysparm_ag');
var ciRec = new GlideRecord('cmdb_ci');
// If we can read the record, check if the sys_ids match
if (ciRec.get(ciID)) {
if (ciRec.getValue('support_group') == agID)
retVal = 'CI support group and assignment group match';
else
retVal = 'CI support group and assignment group do not match';
// Can't read the CI, then they don't match
} else {
retVal = 'CI support group and assignment group do not match';
}
return retVal;
}
});„setValue()“ mit Parameter „displayValue“ auf Referenzfelder anwenden
Wenn Sie „setValue()“ auf ein Referenzfeld anwenden, können Sie den Parameter „displayValue“ einfügen, um zusätzliche Serveraufrufe zu vermeiden.
Wenn Sie setValue() auf ein Referenzfeld anwenden, sollten Sie also den Anzeigewert des Referenzfelds als dritten Parameter angeben. Wenn Sie den Wert ohne den Anzeigewert festlegen, führt die Instanz einen synchronen Aufruf durch, um den Anzeigewert des angegebenen Datensatzes abzurufen. Dieser zusätzliche Roundtrip zum Server kann sich negativ auf die Leistung auswirken.
var id = '5137153cc611227c000bbd1bd8cd2005';
g_form.setValue('assigned_to', id); // Client needs to go back to the server to
// fetch the name that goes with this IDvar id = '5137153cc611227c000bbd1bd8cd2005';
var name = 'Fred Luddy';
g_form.setValue('assigned_to', id, name); // No server call requiredUI-Richtlinien statt Client-Skripts verwenden
Falls möglich sollten Sie statt Client-Skripts UI-Richtlinien verwenden.
- UI-Richtlinien verfügen über ein Feld Reihenfolge, über das Sie vollständig steuern können, in welcher Reihenfolge clientseitige Vorgänge ausgeführt werden sollen.
- Bei UI-Richtlinien ist kein Skript erforderlich, um Felder obligatorisch, schreibgeschützt oder sichtbar zu machen.
Validierung der Eingabe mithilfe eines Client-Skripts
Ein Client-Skript eignet sich hervorragend, um die Eingaben des Benutzers zu validieren.
Eine solche Validierung verbessert die Benutzererfahrung, da der Benutzer bereits vor dem Absenden der Informationen über Datenprobleme informiert wird.
if (g_form.getValue('impact') == '3' && g_form.getValue('priority') == '1')
g_form.showFieldMsg('impact', getMessage('Low impact now allowed with High priority'), 'error');
Client-Skript-Reihenfolge festlegen
Über das Feld „Reihenfolge“ können Sie festlegen, in welcher Reihenfolge Ihre Client-Skripts ausgeführt werden sollen. Durch die Festlegung einer Reihenfolge für die Ausführung der Skripts vermeiden Sie, dass zwei oder mehr Client-Skripts gleichzeitig ausgeführt werden und Konflikte entstehen.
Vorbereitungen
Warum und wann dieser Vorgang ausgeführt wird
Prozedur
DOM-Änderungen vermeiden
Vermeiden Sie nach Möglichkeit Änderungen am DOM (Document Object Model). Solche Änderungen können zu Wartungsproblemen führen, wenn Browser aktualisiert werden.
Verwenden Sie stattdessen die API „GlideForm“, oder ziehen Sie einen anderen Lösungsansatz in Betracht. Im Allgemeinen gilt: Wenn Sie Methoden zur Änderung des DOM verwenden, müssen Sie ein Element im DOM referenzieren. Dazu müssen Sie entweder die ID oder eine CSS-Auswahl verwenden. Beim Referenzieren von vordefinierten DOM-Elementen besteht das Risiko, dass sich die Element-ID oder die Platzierung innerhalb des DOM ändern. Ist das der Fall, funktioniert der Code nicht mehr und/oder generiert Fehler. Machen Sie sich die Auswirkungen von Änderungen klar, gehen Sie mit Bedacht vor und bedenken Sie alle Risiken. Überprüfen Sie diese Objekte, und greifen Sie so wenig wie möglich auf Methoden zur Änderung des DOM zurück.
Globale Client-Skripts vermeiden
Ein globales Client-Skript ist ein Client-Skript, in dem als ausgewählte Tabelle „Global“ festgelegt ist. Für globale Client-Skripts gelten keine Tabelleneinschränkungen. Daher werden sie auf jeder Seite im System geladen, was zu Ladeverzögerungen im Browser führt.
Es hat keinen Nutzen, Skripts dieses Typs auf jeder Seite zu laden.
Als Alternative und für einen modulareren und skalierbareren Ansatz sollten Sie Client-Skripts in eine Basistabelle verschieben (z. B. „Aufgabe[task]“ oder „Configuration Item[cmdb_ci]“), die für alle untergeordneten/erweiterten Tabellen abgeleitet werden kann. Dadurch muss das System die Skripts nicht in jedem UI-Formular laden, beispielsweise nicht auf Homepages oder im Servicekatalog, wo sie wenn überhaupt nur selten benötigt werden.
Code in Funktionen einschließen
Schließen Sie Code in Client-Skripts in Funktionen ein.
Client-Skripts ohne Funktion führen zu Problemen mit dem Bereich von Variablen. Wenn Code nicht in eine Funktion eingeschlossen ist, sind Variablen und andere Objekte auch für alle anderen clientseitigen Skripts verfügbar und freigegeben. Verwenden Sie dann identische Variablennamen, kann es zu Konflikten kommen. Das wiederum kann unerwartete Folgen haben, die schwer zu diagnostizieren und zu beheben sind.
var state = "6";
function onSubmit() {
if(g_form.getValue('incident_state') == state) {
alert("This incident is Resolved");
}
}function onSubmit() {
var state = "6";
if(g_form.getValue('incident_state') == state) {
alert("This incident is Resolved");
}
}Diese Lösung ist sehr viel sicherer, da der Bereich der Variablen state auf die Funktion „onSubmit()“ beschränkt ist. So kann es nicht zu Konflikten zwischen dieser Variable state und Variablen namens state in anderen clientseitigen Skripts kommen.
Nur notwendige Skripts ausführen
Damit Skripts mit langer Ausführungsdauer nicht unnötigerweise ausgeführt werden, sollten Client-Skripts nur notwendige Aufgaben ausführen.
Die nachfolgend aufgeführten Beispiele zeigen, wie sich der jeweilige ursprüngliche Codeausschnitt verbessern lässt. Dabei demonstriert jedes Beispiel eine spezifische Skriptverbesserung, die die Leistung steigert und unnötige Aufrufe vermeidet.
Bedenken Sie dabei dass Client-Skripts kein Feld Bedingung haben. Das bedeutet, dass Skripts des Typs „onLoad()“ und des Typs „onChange()“ bei jedem Laden des entsprechenden Formulars vollständig ausgeführt werden. Dieses Beispiel ist ein ineffizientes Client-Skript des Typs „onChange()“, das immer dann ausgeführt wird, wenn das Feld Configuration Item geändert wird.
//Set Assignment Group to CI's support group if assignment group is empty
function onChange(control, oldValue, newValue, isLoading) {
var ciSupportGroup = g_form.getReference('cmdb_ci').support_group;
if (ciSupportGroup != '' && g_form.getValue('assignment_group) != '')
g_form.setValue('assignment_group', ciRec.support_group.sys_id);
}
In diesem Beispiel haben wir den vorherigen Codeausschnitt verbessert, indem wir die Suche des Typs „getReference()“ bzw. „GlideRecord“ durch einen asynchronen Aufruf des Typs „GlideAjax“ ersetzt haben.
//Set Assignment Group to support group if assignment group is empty
function onChange(control, oldValue, newValue, isLoading) {
var ga = new GlideAjax('ciCheck');
ga.addParam('sysparm_name', 'getSupportGroup');
ga.addParam('sysparm_ci', g_form.getValue('cmdb_ci'));
ga.getXML(setAssignmentGroup);
}
function setAssignmentGroup(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
g_form.setValue('assignment_group', answer);
}
Die Kennzeichnung isLoading ist der einfachste Weg, um zu verhindern, dass unnötiger Code in onChange-Skripts Browserzeit beansprucht. Die Kennzeichnung isLoading sollte am Anfang eines Skripts stehen, das beim Laden des Formulars nicht ausgeführt werden muss. Dieses Skript muss nicht beim Laden des Formulars ausgeführt werden, weil die Logik bereits bei der letzten Änderung des Felds ausgeführt wurde. Durch Hinzufügen der Prüfung isLoading zum Skript wird verhindert, dass bei jedem Formularladen eine cmdb_ci-Suche durchgeführt wird.
Die Kennzeichnung isTemplate gibt an, dass eine Vorlage geladen wird.
//Set Assignment Group to CI's support group if assignment group is empty
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading)
return;
var ga = new GlideAjax('ciCheck');
ga.addParam('sysparm_name', 'getSupportGroup');
ga.addParam('sysparm_ci', g_form.getValue('cmdb_ci'));
ga.getXML(setAssignmentGroup);
}
function setAssignmentGroup(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
g_form.setValue('assignment_group', answer);
}
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading) {}; // run during loading
// rest of script here
}//Set Assignment Group to CI's support group if assignment group is empty
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading)
return;
if (newValue) {
var ga = new GlideAjax('ciCheck');
ga.addParam('sysparm_name', 'getSupportGroup');
ga.addParam('sysparm_ci', g_form.getValue('cmdb_ci'));
ga.getXML(setAssignmentGroup);
}
}
function setAssignmentGroup(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
g_form.setValue('assignment_group', answer);
}//Set Assignment Group to CI's support group if assignment group is empty
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading)
return;
if (newValue) {
if (newValue != oldValue) {
var ga = new GlideAjax('ciCheck');
ga.addParam('sysparm_name', 'getSupportGroup');
ga.addParam('sysparm_ci', g_form.getValue('cmdb_ci'));
ga.getXML(setAssignmentGroup);
}
}
}
function setAssignmentGroup(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
g_form.setValue('assignment_group', answer);
}//Set Assignment Group to CI's support group if assignment group is empty
function onChange(control, oldValue, newValue, isLoading, isTemplate) {
if (isLoading)
return;
if (newValue) {
if (newValue != oldValue) {
if (g_form.getValue('assignment_group') == '') {
var ga = new GlideAjax('ciCheck');
ga.addParam('sysparm_name', 'getSupportGroup');
ga.addParam('sysparm_ci', g_form.getValue('cmdb_ci'));
ga.getXML(setAssignmentGroup);
}
}
}
}
function setAssignmentGroup(response) {
var answer = response.responseXML.documentElement.getAttribute("answer");
g_form.setValue('assignment_group', answer);
}