Ik heb een kleine tutorial geschreven hoe verschillende acties in de browser asynchroon verschillende acties uitvoeren op de server, en op de client weer de juiste result eruitgehaald wordt waar een actie op uitgevoerd wordt. Ik zou graag feedback willen of onderstaande methode de juiste methode is, of dat het anders of beter kan.
Gegevens asynchroon updaten via ICallBackEventHandler
In deze tutorial beschrijf ik hoe je asynchroon de browser een berichtje kunt laten sturen naar de server, de server een proces laat uitvoeren, en daarna een berichtje terugstuurt naar de browser. Dit berichtje kan dan gebruikt worden voor verdere actie van de browser, bijvoorbeeld de innerHTML van een DIV aan de laten passen. Op die manier is er geen postback vereist voor verversen van de data.
Een extra aanpassing die ik heb gemaakt, is dat het mogelijk wordt verschillende controls op je pagina verschillende dingen asynchroon te kunnen laten doen.
Laten we stellen dat je class MyClass heet.
Dan moet je deze ook de ICallBackEventHandler interface laten implementeren. In onderstaand voorbeeld wordt deze naast UserControl of Page gezet.
public class MyClass : System.Web.UI.UserControl, System.Web.UI.ICallBackEventHandler
Voeg using System.Web.UI; toe aan de using-statements.
Zet in de Page_Load event van de class de volgende code, want deze injecteert een stuk javascript in de aspx/ascx-pagina:
Dit betekent dat als de CallServer functie in je browser aangeroepen wordt, de RaiseCallBackEvent methode op de server wordt aangeroepen.
Maak dan ook een methode:
Wat er gebeurt is, omdat er maar één lange string meegegeven wordt moeten we kunnen bepalen welke browseraanroep de callback veroorzaakt heeft, maar ook de callbackResult terug naar de browser moet zo'n identificatie bevatten. Vandaar de "ProcessA:" voor de returnstring, omdat we dat met de split functie er weer af kunnen strippen.
Laten we nu naar de javascript gaan. We hebben 2 functies die door bijv. een onclick="callBackProcessA()" aangeroepen kunnen worden.
Zet onderstaande code in je javascript sectie van de aspx/ascx pagina. Heb je die niet zet het dan tussen een <script type="text/javascript"> </script> tag.
Je kunt naar believen processen toevoegen door gewoon te copy/pasten en de procesnamen de juiste naam te geven.
Is dit de juiste manier of kan dit beter/anders?
Gegevens asynchroon updaten via ICallBackEventHandler
In deze tutorial beschrijf ik hoe je asynchroon de browser een berichtje kunt laten sturen naar de server, de server een proces laat uitvoeren, en daarna een berichtje terugstuurt naar de browser. Dit berichtje kan dan gebruikt worden voor verdere actie van de browser, bijvoorbeeld de innerHTML van een DIV aan de laten passen. Op die manier is er geen postback vereist voor verversen van de data.
Een extra aanpassing die ik heb gemaakt, is dat het mogelijk wordt verschillende controls op je pagina verschillende dingen asynchroon te kunnen laten doen.
Laten we stellen dat je class MyClass heet.
Dan moet je deze ook de ICallBackEventHandler interface laten implementeren. In onderstaand voorbeeld wordt deze naast UserControl of Page gezet.
public class MyClass : System.Web.UI.UserControl, System.Web.UI.ICallBackEventHandler
Voeg using System.Web.UI; toe aan de using-statements.
Zet in de Page_Load event van de class de volgende code, want deze injecteert een stuk javascript in de aspx/ascx-pagina:
C#:
1
2
3
| string cbReference = cm.GetCallbackEventReference(this, "arg", "ReceiveServerData", ""); string callbackScript = "function CallServer(arg, context) {" + cbReference + "; }"; cm.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true); |
Dit betekent dat als de CallServer functie in je browser aangeroepen wordt, de RaiseCallBackEvent methode op de server wordt aangeroepen.
Maak dan ook een methode:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| public void RaiseCallbackEvent(String eventArgument) { string[] eventArgs = eventArgument.Split(':'); // Split in de aanroeper en de argumenten switch (eventArgs[0]) { case "DoProcessA": this.DoProcessA(eventArgs[1]); // Roep methode A aan break; case "DoProcessB": this.DoProcessB(eventArgs[1]); // Roep methode B aan break; // vul aan met hoeveel je wilt. Maak ook de methods. } } private void DoProcessA(string arg) { // Process het argument. Dit is de string die vanaf de browser gestuurd werd. string result = "Resultaat van proces A"; Session["ResultProcessA"] = result; // Zet het in de session // GetCallBackResult wordt aangeroepen als het proces klaar is. } private void DoProcessB(string arg) { string result = "Resultaat van proces B"; Session["ResultProcessB"] = result; } // Deze method wordt aageroepen als DoProcess klaar is. Het resultaat wordt uit de sessionvariabele gehaald. De return van deze method stuurt het resultaat in een string door naar de browser en komt daar in de javascriptfunctie ReceiveServerData binnen. public string GetCallbackResult() { if (Session["ResultProcessA"] != null) { string callBackResult = Session["ResultProcessA"].ToString(); Session["ResultProcessA"] = null; // Weer null maken return "ProcessA:" + callBackResult; // "ProcessA:" moet mee. Dit wordt eraf gesplit in de browser voor verdere processing. } if (Session["ResultProcessB"] != null) { string callBackResult = Session["ResultProcessB"].ToString(); Session["ResultProcessB"] = null; return "ProcessB:" + callBackResult; } return ""; } |
Wat er gebeurt is, omdat er maar één lange string meegegeven wordt moeten we kunnen bepalen welke browseraanroep de callback veroorzaakt heeft, maar ook de callbackResult terug naar de browser moet zo'n identificatie bevatten. Vandaar de "ProcessA:" voor de returnstring, omdat we dat met de split functie er weer af kunnen strippen.
Laten we nu naar de javascript gaan. We hebben 2 functies die door bijv. een onclick="callBackProcessA()" aangeroepen kunnen worden.
Zet onderstaande code in je javascript sectie van de aspx/ascx pagina. Heb je die niet zet het dan tussen een <script type="text/javascript"> </script> tag.
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| function callBackProcessA() { // voer een javascript proces uit. var myProcessResult = "Resultaat van process"; CallServer("DoProcessA:" + myProcessResult, "ProcessA"); } function callBackProcessB() { // idem voor Process B. (verander de A's in een B), enz. voor meerdere processen } // Hier komt het resultaat van het proces weer de browser binnen, asynchroon! function ReceiveServerData(arg, context) // context wordt helaas niks bruikbaars mee gedaan door .Net, maar moet er wel in. { var args = arg.split(":", 2); // Splitten zodat we kunnen achterhalen welk process feedback geeft. var caller = args[0]; // De caller van de server dus var argParams = args[1]; // De argumenten switch (caller) { case "ProcessA": var resultaatVanServer = argParams; // Doe iets met die var, bijvoorbeeld de innerHTML van een div wijzigen. // Er bestaat bijvoorbeeld een <div id="infoDiv"></div>, dan doe je: var infoDiv = document.getElementById("infoDiv"); infoDiv.innerHTML = resultaatVanServer; // en de tekst wijzigt zonder dat de pagina ververst is. break; case "ProcessB": var resultaatVanServer = argParams; // doe iets ermee break; } |
Je kunt naar believen processen toevoegen door gewoon te copy/pasten en de procesnamen de juiste naam te geven.
Is dit de juiste manier of kan dit beter/anders?