In enkele gevallen wilt u misschien verdere informatie uit R ophalen, die dan in de UI van uw plugin wordt weergegeven. U wilt, bijvoorbeeld, een selectie aanbieden van de levels van een factor die de gebruiker heeft geselecteerd voor analyse. Vanaf versie 0.6.2 van RKWard is dit mogelijk. Voordat we beginnen, is het belangrijk dat u op de hoogte bent van een aantal valkuilen:
R-code, die gestart wordt vanuit de logica van een UI van een plugin, wordt verwerkt tijdens de event loop van R, wat betekent dat die kunnen lopen terwijl andere berekeningen aan de gang zijn. Dit is om er zeker van te zijn, dat de UI van uw plugin bruikbaar is, ook al is R druk bezig met andere dingen. Maar, dit maakt het werkelijk belangrijk dat uw code geen bijeffecten heeft, in het bijzonder:
Maak geen toewijzingen (assignments) in .GlobalEnv of welke andere niet-lokale omgeving dan ook.
Stuur niets naar het uitvoerbestand.
Plot niets op het scherm.
Doe, in het algemeen, niets dat zij-effecten heeft. Uw code kan informatie inlezen, maar niets "doen".
Met dit in gedachten, is hier het algemene patroon. U gebruikt dit in een sectie van ge-scripte UI-logica:
<script><![CDATA[
let update = gui.addChangeCommand ("variable", function () {
gui.setValue ("selector.enabled", 0);
variable = gui.getValue ("variable");
if (variable == "") return;
new RCommand('levels (' + variable + ')', "myid").then(result =
> {
gui.setValue ("selector.enabled", 1);
gui.setListValue ("selector.available", result);
}).catch(msg =
> {
if (msg === "outdated") return; // commando was geannuleerd, omdat er een nieuwe op het punt staat te arriveren -> benign
// mogelijk ander foutbehandeling, msg bevat de waarschuwing en geproduceerd foutmelding,
// als het commando mislukte bijv.:
gui.setListValue ("selector.available", Array ("ERROR:", msg));
});
}
]]></script>
Hierin is, variabele een eigenschap met een objectnaam (bijv. in een <varslot>). Wanneer die verandert, wilt u het tonen van levels in de <valueselector>, met de naam selector bijwerken. De sleutelfunctie hier is het constructiecommando new RCommand(), met als eerste parameter de opdracht welke tekenreeks te starten. Let erop dat de opdracht asynchroon wordt gedaan, wat de zaak wat complexer maakt. Ten eerste moet u er voor zorgen dat uw <valueselector> uit blijft staan, zolang het geen bijgewerkte informatie bevat. Ten tweede, omdat de gebruiker wijzigingen kan doen, snel, meer dan één commando misschien heeft gegenereerd, voordat we enig resultaat ontvangen. Dus moet u er zeker van zijn om alleen op het meest recente commando te acteren.
Om met asynchroon zijn te werken, wat hier is teruggekeerd, is een object Promise. Meer informatie over deze krachtige javascript functie is te vinden in op het internet. Het belangrijkste hier is te weten dat achtervoegen van een .then() statement u het specificeren biedt wat zal gebeuren wanneer het commando is voltooid en een .catch() statement gebruikt kan worden om fouten af te handelen. Opnieuw, bedenk, dat het blok .then() niet onmiddellijk wordt uitgevoerd. Om te de implicaties hiervan te begrijpen, kan het behulpzaam zijn, gedurende ontwikkeling, om een Sys.sleep(1); in uw R commando in te voegen, om te zien wat er gebeurt, wanneer een commando niet volledig, onmiddellijk, gereed komt.
Tenslotte, om te delen met meerdere commando's die gegenereerd worden, kunt u een tweede argument specificeren bij het new RCommand(), ("myid", in dit voorbeeld). Alle commando's met dezelfde (vrij gekozen) identifier zal begrepen worden te behoren tot dezelfde wachtrij. RKWard zal dan verzekeren dat alleen het laatst commando het blok .then() zal starten, terwijl alle verouderde commando's zullen arriveren in het blok .catch(). Hier kunnen verouderde commando's geïdentificeerd worden, omdat de tekenreeks "outdated" wordt doorgegeven als hun waarde, terwijl voor alle andere mogelijke fouten, de waarschuwingen en foutmeldingen samen worden doorgegeven.
Let erop dat dit voorbeeld een beetje eenvoudiger is gemaakt. In werkelijkheid moet u verdere voorzorgsmaatregelen treffen, bijv. het voorkomen van een extreem aantal levels in de selector. Het goede nieuws is dat u dit waarschijnlijk niet allemaal zelf moet doen. Bovenstaand voorbeeld komt uit de rkward::level_select-plugin, bijvoorbeeld, die u eenvoudig kunt inbedden in uw eigen plugin. U kunt zelfs een andere te starten expressie opgeven in plaats van levels().
Opmerking
In eerdere versies van RKWard werden R-commands uitgevoerd met gebruik van een ietwat complexere functie doRCommand(). U zou dat nog steeds in sommige plug-ins kunnen zien, maar het is niet aanbevolen om in nieuwe code te gebruiken.