2012-01-29 5 views
18

Sto cercando di capire come Backbone.js, Slim PHP e Paris/Idiorm potrebbero funzionare insieme e sto avendo problemi a completare il flusso, a partire dai dati degli attributi del modello, fino al database. PROBLEMA: cosa viene inviato al mio server quando eseguo model.save()?Come caricare i dati del modello backbone in DB tramite Slim php e Paris

lato client: Backbone.js

var Donut = Backbone.Model.extend({ 
    defaults: { 
     name: null, 
     sparkles: false, 
     creamFilled: false 
    }, 
    url: function() { 
     return '/donut'; 
    } 
}); 

var bostonCream = new Donut({ 
    name: 'Bawston Cream', 
    sparkles: true, 
    creamFilled: true 
}); 

bostonCreme.save(); // <-- Problem: Not sure what & format this is sending 

Credo che quanto sopra è il mio problema principale. La mia comprensione è che il backbone, per impostazione predefinita, saprà inviare i dati POST dal momento che è nuovo. Lo invia a/donut che viene instradato, ma la domanda che ho è COSA viene inviata? E in quale formato? Il risultato che voglio è quello di salvare quegli attributi di ciambella sul mio DB. Posso passare questo codice lato server un JSON come questo utilizzando jQuery $ .post() ...

var myDonut = {"name":"Jelly Filled", "sparkles":false, "creamFilled":true}; 
$.post('http://localhost/donut', myDonut); 

... e prende felicemente, lo salva al mio database. Ma con la configurazione corrente cercando di inviare i miei dati di donut backbone, ottengo POST 500 Internal Server Error. Di seguito ho un codice sul lato server.

lato server: Slim PHP w/Parigi

class Donut extends Model {} 

$app->post('/donut', function() use ($app) { // Slim framework routes my POST... 

    $donuts = Model::factory('Donut')->create(); // Paris stuff... 

    $donuts->name = $app->request()->post('name'); // Slim request parameters... 
    $donuts->sparkles = $app->request()->post('sparkles'); 
    $donuts->creamFilled = $app->request()->post('creamFilled'); 

    $donuts->save(); // Paris... Save name, sparkles, and creamFilled to my DB 
}); 

Ho la sensazione che la risposta è là fuori, ma tutti gli esempi che ho guardato sembra mancare un pezzo del puzzle o un altro e Non riesco a capire "A-hA!" momento. Vi ringrazio in anticipo e mi scuso se questa è una domanda davvero ignorante. :-P

SEGUITO/EDIT: 1

Potete incollare i messaggi di errore?

Ottengo un POST http://localhost:8888/donut 500 (Errore interno server) nello stato corrente. Posso ottenere maggiori informazioni con il seguente codice.

bostonCream.save({}, { // REPLACE bostonCream.save(); 
    success: function(model, response) { 
     console.log('SUCCESS:'); 
     console.log(response); 
    }, 
    error: function(model, response) { 
     console.log('FAIL:'); 
     console.log(response); 
    } 
}); 

Ora quando ho eseguito save(), ho ancora ottenere l'errore di spina dorsale 500, ma anche XMLHttpRequest come la mia risposta FAIL. L'unico notevole indizio da XMLHttpRequest è responseText = SQLSTATE [23000]: Violazione del vincolo di integrità: 1048 Il "nome" colonna non può essere nullo.

Quindi la mia ipotesi è che 1) Sto confondendo qualcosa con il save() in quanto non sta acquisendo correttamente i miei attributi, 2) Attualmente sta inviando i miei attributi in un formato che il mio server non è Riconoscimento con i metodi standard $ app-> request() -> post() Slim (Non sembra fare molto quando provo ad accedere direttamente con $ _POST), 3) Il mio server non è configurato correttamente per prendere il tipo di dati che viene inviato.

Un'altra cosa che ho notato, anche se non so che cosa fare di esso è che quando aggiungo

echo $_POST; 

Si ritorna a me un array vuoto. Mi dà ancora il FAIL. Tuttavia, se lo faccio ...

echo json_encode($_POST); 

Mi dà un SUCCESSO e la risposta è un []. Niente dentro. Chiaramente i miei dati POST sono ancora vistosi.

risposta

30

Mi è venuta una soluzione per completare il problema: come ottenere dati da client a server usando il backbone di default save() e .sync - passato al framework php Slim e passando per Paris/Idiorm al mio DB .

Sono compresi il mio codice di lavoro aggiornata qui sotto:

lato client: Backbone.js

var Donut = Backbone.Model.extend({ 
    defaults: { 
     name: null, 
     sparkles: false, 
     creamFilled: false 
    }, 
    url: function() { 
     return '/donut'; 
    } 
}); 

var bostonCream = new Donut({ 
    name: 'Bawston Cream', 
    sparkles: true, 
    creamFilled: true 
}); 

bostonCream.save(); 

/***** If you want to check out the response to save() ? *** 
bostonCream.save({}, { 
    success: function(model, response) { 
     console.log('SUCCESS:'); 
     console.log(response); 
    }, 
    error: function(model, response) { 
     console.log('FAIL:'); 
     console.log(response); 
    } 
}); 
************************************************************/ 

Sever-side: Slim PHP w/Parigi/Idorm

class Donut extends Model {} 

$app->post('/donut', function() use ($app) { 

    $donuts = Model::factory('Donut')->create(); 

    /* EDIT: Works... but not the Slim way 
    $parameters = json_decode(file_get_contents('php://input'), true); 
    $donuts->name = $parameters['name']; 
    $donuts->sparkles = $parameters['sparkles']; 
    $donuts->creamFilled = $parameters['creamFilled']; */ 

    /* SLIM: Using Slim Request Object */ 
    $requestBody = $app->request()->getBody(); // <- getBody() of http request 
    $json_a = json_decode($requestBody, true); 
    $donuts->name = $json_a['name']; 
    $donuts->sparkles = $json_a['sparkles']; 
    $donuts->creamFilled = $json_a['creamFilled']; 

    $donuts->save(); 

    // echo json_encode($parameters); // Prove you've captured POST data, send it back 
} 

Ora il mio codice utilizza felicemente le impostazioni predefinite di Backbone.js (nessuna modifica alla sincronizzazione) e l'invio corretto informazioni sull'attributo odel al mio server che sembra accettare con successo i dati e salvarli sul mio DB.

La chiave qui sembra essere questa linea ...

/* $parameters = json_decode(file_get_contents('php://input'), true); */ 
// EDITED: getBody() method not documented in Develop Doc, only Stable @ time of post 

$requestBody = $app->request()->getBody(); 
+0

Sei un genio! per questo un plus per la domanda + risposta. Grazie! –

+0

Ciao orangewarp, ho dovuto affrontare lo stesso problema qui usando Backbone e Slim. Trovo molto strano però che devi usare getBody() mentre è più appropriato usare post() o put() a seconda della tua richiesta. – Maarten

+0

Puoi avere Slim analizza il JSON per te. Dovrai comunque chiamare getBody(). Il metodo post() della richiesta non rispetta l'analisi eseguita dal middleware ContentType e sembra gestire solo i dati del modulo. Dopo aver istanziato $ app, fai questo: $ app-> add (new \ Slim \ Middleware \ ContentTypes()); // Ottenere l'analisi JSON in entrata analizzata. Dopodiché, getBody() restituisce una bella serie di dati analizzati. –

1

Se vuoi sapere "che cosa viene inviato esattamente al server", dovresti dare un'occhiata allo Backbone.sync function in Backbone's code. È molto ben documentato, passo dopo passo. Quindi, il modo più pulito per ottenere ciò di cui hai bisogno è scrivere la tua funzione di sincronizzazione, ispirata alla sincronizzazione di Backbone.

Inoltre, un modo rapido per vedere cosa viene inviato al server è utilizzare la console di debug del browser (scheda Rete). È possibile confrontare qui ciò che viene inviato da Backbone contro ciò che viene inviato quando si usa $ .post direttamente. Si prega di inviare queste informazioni se avete bisogno di più aiuto!

+0

te lo rileggere la documentazione Backbone.sync. La mia comprensione finora è che ha già un comportamento predefinito, che voglio capire! :-) Da quello che ho capito, prende gli attributi del mio modello e li serializza in JSON, lo invia, e si aspetta un JSON in cambio dal server se apporto modifiche all'oggetto. Usando il mio esempio pubblicato, quando lo faccio ... bostonCream.save(); Mi aspettavo qualcosa di simile ... { "name": "Bawston Creme", "brilla": true, "creamFilled": true} da inviare. Se questo fosse vero, dovrebbe funzionare con il mio codice sopra ma non è così. Sospettare! – jmk2142

+0

Inoltre, per quanto riguarda l'utilizzo della console. Con $ .post di jQuery c'è un callback di successo o fallimento che posso usare su console.log (dati). Posso echo $ _POST e vedere cosa viene catturato o meno. Ma con Backbone, non sono sicuro di come vedere il mio echo $ _POST. bostonCream.save() invierà la richiesta e restituirà ... qualcosa? Qualcosa di simile sarebbe il modo corretto per verificare cosa viene restituito? bostonCream.save ({}, {success: function (model, response) {console.log ('SUCCESS'); console.log (response);}, errore {console.log ('FAIL'); console.log (risposta);}}); – jmk2142

+0

Mi spiace volevo dire "leggi il codice sorgente Backbone" (ho postato un link alla documentazione, colpa mia). In backbone.sync vedrai cosa succede. – Blacksad

0

spina dorsale invia i dati al server JSON PHP backend, che si dovrebbe esporre il RESTful API per rispondere a http verbo come ottenere, posta, parole, eliminare e così via

vostro api backend è responsabile della comunicazione con il database .

Non sono sicuro di SLIM PHP. sembra gestire la richiesta. Puoi incollare i messaggi di errore?

+0

Ho aggiornato il codice precedente con altri messaggi di errore dopo il test. Farò ancora un po 'di lettura come suggerisce @Blacksad. – jmk2142