2011-11-08 12 views
6

Le specifiche HTML5 per ExecuteSQL include un callback successo e un rifiuto di callback:Wrapping WebSQL ExecuteSQL chiama in jQuery differite/promessa

db.transaction(function(tx) {  
    tx.executeSql('SELECT * FROM MyTable WHERE CategoryField = ?', 
    [ selectedCategory ], 
    function (tx, rs) { displayMyResult(rs); }, 
    function (tx, err) { displayMyError(err); }); 
}); 

Se fossi usando jQuery, c'è un modo per implementare questo utilizzando il nuovo jQuery promessa/rinviato hotness?

risposta

2

Stavo aspettando una risposta, ma niente fino ad ora, quindi farò un tentativo. Non posso eseguire questo, quindi mi scuso per eventuali errori.

Siete alla ricerca di qualcosa di simile:

function deferredTransaction(db,transaction,transactionFunction(transaction)) { 
    me=this; 
    return $.Deferred(function(deferedObject){ 
     db.transaction(transactionFunction(transaction), 
     function(tx,rs) { me.resolve(tx,rs); }, 
     function(tx,err) { me.reject(tx,err); }); 
    }).promise(); 
} 

dtx=deferredTransaction(db,tx,function(tx) {  
    tx.executeSql('SELECT * FROM MyTable WHERE CategoryField = ?', 
    [ selectedCategory ]); 
dtx.then(function (tx, rs) { displayMyResult(rs); }, 
    function (tx, err) { displayMyError(err); }); 
3

Ci siamo imbattuti in questa domanda mentre alla ricerca di qualcosa di diverso, ma penso di avere un po 'di codice di modello che permette di iniziare avvolgendo query WebSQL in La promessa jQuery.

Questo è un campione da sqlProviderBase a $.extend sul proprio provider. Ho un esempio con un taskProvider e una pagina che chiamerebbe allo taskProvider nell'evento di visualizzazione della pagina. È piuttosto scarso, ma spero che aiuti gli altri ad orientarsi nella giusta direzione per avvolgere le query in una promessa per una migliore gestione.

var sqlProviderBase = { 

    _executeSql: function (sql, parms) { 

     parms = parms || []; 

     var def = new $.Deferred(); 

     // TODO: Write your own getDb(), see http://www.html5rocks.com/en/tutorials/webdatabase/todo/ 
     var db = getDb(); 

     db.transaction(function (tx) { 
      tx.executeSql(sql, parms, 
      // On Success 
      function (itx, results) { 
       // Resolve with the results and the transaction. 
       def.resolve(results, itx); 
      }, 
      // On Error 
      function (etx, err) { 
       // Reject with the error and the transaction. 
       def.reject(err, etx); 
      }); 
     }); 

     return def.promise(); 
    } 
}; 

var taskProvider = $.extend({}, sqlProviderBase, { 

    getAllTasks: function() { 

     return this._executeQuery("select * from Tasks"); 

    } 

}); 

var pageThatGetsTasks = { 
    show: function() { 

     taskProvider.getAllTasks() 
        .then(function(tasksResult) { 

         for(var i = 0; i < tasksResult.rows.length; i++) { 
          var task = tasksResult.rows.item(i); 

          // TODO: Do some crazy stuff with the task... 
          renderTask(task.Id, task.Description, task.IsComplete); 

         } 

        }, function(err, etx) { 

         alert("Show me your error'd face: ;-[ "); 

        }); 

    } 
}; 
+0

Grazie Jacob! http://tutsplus.com/lesson/deferreds/?WT.mc_id=learnjquery parla anche di differiti. Sto guardando il tuo codice e cade in linea con ciò che Jeffrey Way dice di fare. –

7

Volevo solo aggiungere un altro esempio.

(function() { 
    // size the database to 3mb. 
    var dbSize = 3 * 1024 * 1024, 
     myDb = window.openDatabase('myDb', '1.0', 'My Database', dbSize); 

    function runQuery() { 
     return $.Deferred(function (d) { 
      myDb.transaction(function (tx) { 
       tx.executeSql("select ? as Name", ['Josh'], 
       successWrapper(d), failureWrapper(d)); 
      }); 
     }); 
    }; 

    function successWrapper(d) { 
     return (function (tx, data) { 
      d.resolve(data) 
     }) 
    }; 

    function failureWrapper(d) { 
     return (function (tx, error) { 
      d.reject(error) 
     }) 
    }; 

    $.when(runQuery()).done(function (dta) { 
     alert('Hello ' + dta.rows.item(0).Name + '!'); 
    }).fail(function (err) { 
     alert('An error has occured.'); 
     console.log(err); 
    }); 

})() 
+0

Hmmm. Penso che chiameresti successWrapper (tx, data) invece di successWrapper (d). JavaScript è difficile. –

+0

La sfida che avevo affrontato era mantenere l'oggetto posticipato nell'ambito, dopo aver chiamato executeSql. Creando una funzione che restituisce una funzione, ho raggiunto questo obiettivo. – JoshRoss

2

trovo che avvolgendo la transazione differita in una funzione e tornare la promessa crea una ricerca e riutilizzabile implementazione pulita del modello/promessa differita.

var selectCategory = function() { 
    var $d = $.Deferred(); 

    db.transaction(
     function(tx) { 
      tx.executeSql(
       "SELECT * FROM MyTable WHERE CategoryField = ?" 
       , [selectedCategory] 
       , success 
       , error 
      ) 
     } 
    ); 

    function success(tx, rs) { 
     $d.resolve(rs); 
    } 

    function error(tx, error) { 
     $d.reject(error); 
    } 

    return $d.promise(); 
}; 

selectCategory() 
    .done(function(rs){ 
     displayMyResult(rs); 
    }) 
    .fail(function(err){ 
     displayMyError(err); 
    });