ASP.NET

UserControl dynamisch laden - Update und jQuery-Plugin

In meinem letzten Artikel UserControls mit Properties/Konstruktoren dynamisch laden (Server und Client) habe ich dargestellt, mit welch relativ geringem Aufwand man komplexe ASP.NET-Steuerelemente auch per Javascript über einen WebService in eine Seite injizieren kann. Es geht aber noch besser...

Das Update

Mein Javascript-Code ist, für die mehrmalige Verwendung innerhalb eines Projekts, schon ein ziemlicher Brocken (20-30 Zeilen, ja nachdem wie leserlich man es haben möchte) und so drängt sich ein Refactoring quasi schon auf. Grund dafür ist natürlich der recht umfangreiche AJAX-Aufruf mittels jQuery.

Zudem fiel mir auf, dass ich einen inhaltlichen Fehler begangen habe. In der Javascript-Methode getElementHtml wird im Erfolgfall das Element direkt an den Container gehängt, was man bei dem gewählten Methodennamen nicht direkt erwarten würde. Shame on me...

Um nun die Routine zu entzerren und allgemeingültiger zu halten, habe ich ihr zwei weitere Eingabeargumente namens successFunction und errorFunction verpasst, die definieren was im Erfolgs- bzw. Fehlerfall passieren soll.

function getElementHtml(iElementNo,
			sElementText, 
			sElementClass, 
			successFunction,
			errorFunction) {

	...

    //Abruf des WebService
    $.ajax({

		...
		
		success:
		    function(sMsg) {
				successFunction(sMsg.d);
		    },
		error:
		    function(XMLHttpRequest,
			     	 textStatus, 
			     	 errorThrown) {
				errorFunction(XMLHttpRequest.responseText);
	    	}
    });
}

Aufgerufen wird die Methode nun folgendermaßen:

getElementHtml(iElementNo,
			   sElementText,
			   sElementClass,
			   function(sHtml) {
			   		$("#container").append(sHtml)
			   },
			   handleServiceError);

Eine weitere Refaktorisierung ist in Bezug auf die in Methode enthaltenen "hard-gecodeten" Variablen wie sUrl, sCtlPath, usw. sicherlich möglich, aber ich verzichte zu diesem Zeitpunkt einmal darauf, denn die Methode heißt ja immer noch GetElementHtml, weil das Steuerelement element.ascx heißt.

Das jQuery-Plugin

Bei der Recherche zum o.g. Artikel, bin ich über einen Beitrag von Roberto Bez mit dem hübschen Namen jQuery Plugin selbstgemacht - Dynamisches laden von ASP.NET Controls gestolpert, der direkt mein Aufsehen erregte und von mir umgesetzt werden wollte.

Na denn ... hier ist es, ascxLoader im zerbit-Style:

(function($) {
    $.fn.ascxLoader = function(params) {
        
        //Referenz auf den Container
        var obj = $(this);

        //Standardwerte
        var defaults = {
            servicePath: "",
            serviceMethod: "",
            controlPath: "",
            properties: {},
            successFunction: function(sHtml){obj.html(sHtml)},
            errorFunction: alert
        };
        
        //Standards und Parameter zusammenführen
        var config = $.extend(defaults, params);

        //JSON-String erzeugen
        var sData = JSON.stringify({
            controlLocation: config.controlPath,
            properties: config.properties
        });
        
        //Abruf des WebService
        $.ajax({
            type: "POST",
            url: config.servicePath + '/' + config.serviceMethod,
            contentType: "application/json; charset=utf-8",
            data: sData,            
            dataType: "json",
            success: 
                function(result) {
                	config.successFunction(result.d);
            },
            error:
                function(xmlReq,
                         textStatus,
                         errorThrown) {
                    config.errorFunction(xmlReq.responseText);                    
                }
        });
    }
})(jQuery);

Ein paar Worte zum Plugin-Code...

Im Gegensatz zu Roberto, verwende ich nur einen Eingabeparameter namens param, in den alles gepackt wird, was das Plugin braucht.

Die WebService-Url habe ich in zwei Teile (servicePath und serviceMethod) zerlegt, denn oftmals ist es so, dass man nur einen WebService mit vielen darin enthaltenen Methoden entwickelt und dann reduziert sich die Parameterliste um einen Punkt, sofern man im Plugin einen Standard im default-Objekt definiert hat. In meinem Beispiel habe ich die Standards einfach mal leer gelassen.

Weitere Parameter sind properties, welches das Objekt entgegennimmt, in dem die Eigenschaften des UserControls enthalten sind, errorFunction mit dem man definieren kann, welche Fehlerroutine ausgeführt werden soll, wenn der Service-Abruf scheitert und successFunction für den Erfolgsfall, d.h. die Verarbeitung des abkommenden Html-Codes.

Der Aufruf des Plugins ist, wie bei jQuery üblich, leicht zu überschauen:

$("#container").ascxLoader({
	servicePath: "service/ScriptService.asmx",
	serviceMethod: "GetControlHtmlWithProperties",
	controlPath: "~/controls/element.ascx",
	properties: { 
		'ElementNo': iElementNo, 
		'ElementText': sElementText, 
		'ElementClass': sElementClass },
	successFunction: 
		function(sHtml) {
			$("#container").append(sHtml)
	},
	errorFunction: handleServiceError
});

Voilá ... ein Einzeiler!

Dirty Code

Einem geübten Betrachter wird der besondere Parameter manupulation aufgefallen sein und wie er im Plugin verarbeitet wird. Er ist dazu da, zu bestimmen, mit welcher jQuery-Methode nach dem erfolgreichen Abruf des Steuerelement-Codes weiterverfahren werden soll.
...
ich habe bislang keine bessere Idee...!?

  • Oh doch ...!

    Für alle die den Artikel schon gelesen haben: es gibt eine bessere Lösung als mit eval irgendwelche jQuery-Methoden ausführen zu lassen! Manchmal ist es einfach schlicht zu spät, um noch geradeaus denken zu können ;)

    Ich hatte es weiter oben bereits vorgeführt: Übergabe einer Function mit einem String-Parameter. Standard-Methode ist html, also das Ersetzen des kompletten Container-Inhalts. Der oben stehende Code und der Download sind bereits aktualisiert.

Happy Coding ;)

Downloads

LoadControlWithParameter2.zip
kick it on dotnet-kicks.de AddThis 0 wikio-Stimme(n) Trackback-Url...

2 Kommentare bislang...

  • Hallo Kristof,
    vielen Dank für deinen Artikel! Leider funktionieren die Funktionen
    "Element per Javascript hinzufügen (WebService und Properties)" und "Elemente per Javascript hinzufügen (... als jQuery-Plugin)" im Opera nicht... :(
    2
    stevo : Montag, 8. Februar 2010 12:48
  • Hallo Kristof,
    vielen Dank für den Artikel, interessante Erweiterung.
    Persönlich finde ich die Idee mit dem eval() gar nicht mal so schlecht - Ich hätte evtl. noch die manipulation Möglichkeiten "html, text, append, after..." als config variablen im Plugin hinterlegt.

    PS: Hab es als Update bei mir verlinkt!
    1
    Roberto : Dienstag, 3. November 2009 22:46

Dein Kommentar hierzu...


Kommentar-Feed für diesen Beitrag
Gravatare werden unterstützt .:. eMail-Adressen werden nicht veröffentlicht
 

RSS-Feed

Die URL des Standard-Newsfeed von zerbit.de lautet:

http://www.zerbit.de/rssfeed.aspx

Login


 

 

Statistik



kürzlich kommentiert

Artikel 297

  • Datum: 03.11.2009
    Kategorie: ASP.NET
    Zugriffe: 14.094
    Kommentare: 2
    Trackbacks: 0

Letzte Beiträge

Kategorien

Buttons & More

Blog-Roll

Banner Piraten-Partei