Friday, November 16, 2012

(function ($) { }(jQuery)); vs $(function () {});

(function ($) {  }(jQuery)); vs $(function () {});

Un petit retour d'expérience, après être resté bloquer pendant quelques heures, sur une erreur liée à la librairie JqueryMobile. L'erreur est : $.mobile.loader of 'undefined' .

Contexte de l'erreur

  • dans la fonction (function($) {} (jQuery)); je crée un model Backbone, une view Backbone et un routeur Backbone.
  • dans cette même fonction j'instancie mon routeur et Backbone.history.start();
Lorsque je charge la page, je réalise un appel Ajax async pour obtenir une collection d'éléments. Pendant cette appel Ajax, j'utilise la "loading bar" de JQuery Mobile comme ci-dessous :
  1. CollectionModel.fetch({
  2.             beforeSend:function ()
  3.             { $.mobile.loading('show');
  4.             },
  5.             complete: function () {
  6.                 $.mobile.loading('hide');
  7.             }, 
  8.             success: callback
  9.         });
Lors de cette appel, la méthode $mobile.loading n'est pas définit car la librairie JQueryMobile n'est pas encore ready.

Solution

Pour résoudre le problème, il faut tout simplement réaliser l'instanciation du Router et lancé Backbone.history.start() n'ont pas dans (function($) {}(jQuery)) mais plutôt dans $(function() {}); car dans ce cas, on est sur que la librairie $.mobile est chargée et disponible.

La fonction anonyme (function($) {}(jQuery) signifie que le DOM JQuery est ready mais il faut bien dissocier le DOM JQuery et le DOM du Document qui est représenté par la fonction suivante : 
  1. $(function() {});

Récapitulatif

La déclaration des Models, des Views et des Routers Backbonejs doivent être placée dans la fonction anonyme :
  1.  (function($) {} (jQuery)); 
Par contre l’instanciation du router doit être de préférence réalisé dans la fonction :
  1. $(function() {});