wtorek, 15 stycznia 2013

jQuery w Web Partach - zagrożenie wielokrotnego importu pliku jQuery

Jak każdy wie, aby móc wykorzystać bibliotekę jQuery w aplikachach webowych opartych o technologię .NET najpierw trzeba poinformować kompilator, że zamierzamy wykorzystać tą bibliotekę. Podobnie jak innymi plikami .js (javascript) przed pierwszym wykorzystaniem należy podać jej nazwę i miejce w którym się znajduje. Lokalizacja może być lokalna (zazwyczaj) lub zewnętrzna (np. do serwera projektu jQuery).

Zazwyczaj taka informacja znajduje się w nagłówku strony aspx (ewentualnie kontrolki ascx) na stronie z częścią HTML i wygląda następująco:
<script src="/_layouts/Scripts/jquery-1.8.2.min.js" type="text/javascript"></script>
Aby biblioteka jQuery działa poprawnie, na jednej stronie, może znajdować się tylko jedna deklaracja importująca plik z biblioteką jQuery. O ile w przypadku standardowych stron ASP.NET taka, pojedyncza deklaracja jest standardem, o tyle w przypadku Web Partów, które same w sobie są oddzielnymi aplikacjami, umieszczanymi niezależnie od siebie często występują konflikty importu. Każdy z web partów samodzielnie dodaje jQuery do strony, co w przypadku umieszczenia kilku takich web partów z deklaracjami importu na jednej stronie powoduje błędy w działaniu javascriptu na tej stronie.

Rozwiązanie polega na tym, aby plik z biblioteką jQuery wczytywać po stronie serwera w instrukcji warunkowej:

        protected void Page_Init(object sender, EventArgs e)
        {
            var cs = Page.ClientScript;

            if (!cs.IsClientScriptIncludeRegistered("jquery-1.8.2.min.js"))
                cs.RegisterClientScriptInclude("jquery-1.8.2.min.js",
                "/_layouts/Scripts/jquery-1.8.2.min.js");
        }
W podobny sposób możemy wczytać bibliotekę jQuery, gdy nie jest wczytana w postaci kodu javascript umieszczonego na stronie html:


<script type="text/javascript">

       var jQueryScriptOutputted = false;
       function initJQuery() {

             //if the jQuery object isn't available
             if (typeof (jQuery) == 'undefined') {

                    if (!jQueryScriptOutputted) {
                           //only output the script once..
                           jQueryScriptOutputted = true;

                           //output the script
                           document.write("<scr" + "ipt type=\"text/javascript\" src=\"/_layouts/Scripts/jquery-1.8.2.min.js\"></scr" + "ipt>");
                    }
                    setTimeout("initJQuery()", 50);
             }

       }
       initJQuery();

</script>

Takie  rozwiązanie pozwala nam na sytuację, aby wszystkie web party na stronie zaimportowały plik z biblioteką jQuery w wersji 1.8.2 tylko raz. Takie rozwiązanie nie jest jednak do końca idealne, ponieważ wymaga od nas, stosowania biblioteki w jednej i tej samej (najnowszej?) wersji we wszystkich web partach, a w przypadku umieszczenia na stronie web parta wymagającego nowszej wersji biblioteki jQuery przekompilowania i zaktualizowania wersji biblioteki w już istniejących web partach. Gdy tylko poznam sposób, w jaki można obejść te niedogodności postaram się tą informację tutaj umieścić.