Sposoby zapisywania danych modelu Backbone.js?

86

Bardziej interesuję się programowaniem front-end i niedawno zacząłem odkrywać Backbone.js w mojej aplikacji. Chcę utrwalić dane modelu na serwerze.

Czy mógłbyś mi wyjaśnić różne sposoby zapisywania danych modelu (przy użyciu formatu json). Używam języka Java po stronie serwera. Ponadto widziałem głównie REST używany do zapisywania danych. Ponieważ bardziej interesuję się programowaniem frontendowym, nie jestem świadomy REST i innych podobnych rzeczy.

Byłoby wspaniale, gdyby ktoś mógł mi wyjaśnić ten proces na prostym przykładzie.

testndtv
źródło

Odpowiedzi:

272

Zasadniczo modele mają właściwość zwaną atrybutami, które są różnymi wartościami, które może mieć określony model. Backbone używa obiektów JSON jako prostego sposobu na wypełnienie tych wartości przy użyciu różnych metod, które pobierają obiekty JSON. Przykład:

Donuts = Backbone.Model.extend({
    defaults: {
        flavor: 'Boston Cream',  // Some string
        price: '0.50'  // Dollars
    }
});

Aby wypełnić model, można to zrobić na kilka sposobów. Na przykład możesz skonfigurować instancję modelu, przekazując JSON LUB użyć metody o nazwie set (), która przyjmuje obiekt JSON atrybutów.

myDonut = new Donut({'flavor':'lemon', 'price':'0.75'});
mySecondHelping = new Donut();
mySecondHelping.set({'flavor':'plain', 'price':'0.25'});

console.log(myDonut.toJSON());
// {'flavor':'lemon', 'price':'0.75'}
console.log(mySecondHelping.toJSON());
// {'flavor':'plain', 'price':'0.25'}

To prowadzi nas do zapisywania modeli i utrwalania ich na serwerze. Jest mnóstwo szczegółów dotyczących „Co to jest REST / RESTful?” Trudno jest to wszystko wyjaśnić w krótkiej notce tutaj. W szczególności w odniesieniu do zapisywania REST i Backbone, należy się zastanowić nad semantyką żądań HTTP i tym, co robisz ze swoimi danymi.

Prawdopodobnie jesteś przyzwyczajony do dwóch rodzajów żądań HTTP. POBIERZ i OPUBLIKUJ. W środowisku RESTful te czasowniki mają specjalne znaczenie dla określonych zastosowań, które zakłada Backbone. Jeśli chcesz pobrać określony zasób z serwera (np. Model pączka, który ostatnio zapisałem, wpis na blogu, specyfikację komputera) i ten zasób istnieje, wykonujesz żądanie GET. I odwrotnie, jeśli chcesz utworzyć nowy zasób, użyj POST.

Zanim wszedłem do Backbone, nigdy nie dotknąłem następujących dwóch metod żądania HTTP. WSTAW i USUŃ. Te dwa czasowniki mają również szczególne znaczenie dla Backbone. Jeśli chcesz zaktualizować zasób (np. Zmienić smak pączka cytrynowego na pączek limon itp.), Użyj żądania PUT. Jeśli chcesz całkowicie usunąć ten model z serwera, użyj żądania DELETE.

Te podstawy są bardzo ważne, ponieważ w aplikacji RESTful prawdopodobnie będziesz mieć oznaczenie URI, które wykona odpowiednie zadanie w oparciu o rodzaj używanego czasownika żądania. Na przykład:

// The URI pattern
http://localhost:8888/donut/:id

// My URI call
http://localhost:8888/donut/17

Jeśli wykonam polecenie GET do tego URI, otrzymam model pączka z identyfikatorem 17. Numer: id zależy od tego, jak zapisujesz go po stronie serwera. Może to być po prostu identyfikator zasobu pączka w tabeli bazy danych.

Gdybym wprowadził PUT do tego identyfikatora URI z nowymi danymi, zaktualizowałbym go, oszczędzając. A jeśli SKASUJĘ do tego identyfikatora URI, usunie go z mojego systemu.

Dzięki POST, ponieważ nie utworzyłeś jeszcze zasobu, nie będzie on miał ustalonego identyfikatora zasobu. Może docelowy identyfikator URI, który chcę utworzyć zasoby, jest po prostu taki:

http://localhost:8888/donut

Brak fragmentu identyfikatora w URI. Wszystkie te projekty URI zależą od Ciebie i tego, jak myślisz o swoich zasobach. Ale jeśli chodzi o projektowanie RESTful, rozumiem, że chcesz zachować czasowniki swoich działań w żądaniu HTTP i zasoby jako rzeczowniki, które sprawiają, że identyfikatory URI są łatwe do odczytania i przyjazne dla człowieka.

Jesteś wciąż ze mną? :-)

Wróćmy więc do myślenia o Backbone. Backbone jest wspaniały, ponieważ wykonuje dużo pracy dla Ciebie. Aby uratować nasz pączek i pomoc, po prostu robimy to:

myDonut.save();
mySecondHelping.save();

Backbone jest inteligentny. Jeśli właśnie utworzyłeś zasób pączka, nie będzie on miał identyfikatora z serwera. Ma coś, co nazywa się cID, którego Backbone używa wewnętrznie, ale ponieważ nie ma oficjalnego identyfikatora, wie, że powinien utworzyć nowy zasób i wysyła żądanie POST. Jeśli masz model z serwera, prawdopodobnie będzie miał identyfikator, jeśli wszystko się zgadza. W tym przypadku, kiedy zapiszesz () Backbone zakłada, że ​​chcesz zaktualizować serwer i wyśle ​​PUT. Aby uzyskać określony zasób, należy użyć metody Backbone .fetch () i wysyła żądanie GET. Kiedy wywołasz .destroy () na modelu, wyśle ​​DELETE.

W poprzednich przykładach nigdy wyraźnie nie powiedziałem Backbone, gdzie znajduje się identyfikator URI. Zróbmy to w następnym przykładzie.

thirdHelping = Backbone.Model.extend({
    url: 'donut'
});
thirdHelping.set({id:15});  // Set the id attribute of model to 15
thirdHelping.fetch();  // Backbone assumes this model exists on server as ID 15

Backbone UZYSKA trzecią pomoc http://localhost:8888/donut/15Po prostu doda / donut stem do katalogu głównego Twojej witryny.

Jeśli NADAL jesteś ze mną, dobrze. Myślę. Chyba że jesteś zdezorientowany. Ale i tak będziemy brnąć dalej. Druga część to strona SERWERA. Mówiliśmy o różnych czasownikach HTTP i semantycznym znaczeniu tych czasowników. Znaczenie, które Ty, Backbone ORAZ wasz serwer musicie dzielić.

Twój serwer musi zrozumieć różnicę między żądaniami GET, POST, PUT i DELETE. Jak widzieliście w powyższych przykładach, GET, PUT i DELETE mogą wskazywać na ten sam URI. http://localhost:8888/donut/07Jeśli twój serwer nie potrafi rozróżnić tych żądań HTTP, będzie bardzo zdezorientowany, co zrobić z tym zasobem.

Wtedy zaczynasz myśleć o kodzie końcowym swojego serwera RESTful. Niektórzy lubią Rubiego, inni lubią .net, ja lubię PHP. Szczególnie podoba mi się mikro-framework SLIM PHP. SLIM PHP to mikro-framework, który posiada bardzo elegancki i prosty zestaw narzędzi do obsługi czynności RESTful. Możesz zdefiniować trasy (URI) jak w powyższych przykładach iw zależności od tego, czy wywołanie to GET, POST, PUT czy DELETE, wykona właściwy kod. Istnieją inne rozwiązania podobne do SLIM, takie jak Recess, Tonic. Uważam, że większe frameworki, takie jak Cake i CodeIgniter, również robią podobne rzeczy, chociaż lubię minimalne. Czy powiedziałem, że lubię Slim? ;-)

Tak może wyglądać fragment kodu na serwerze (tj. Szczególnie w odniesieniu do tras).

$app->get('/donut/:id', function($id) use ($app) {
    // get donut model with id of $id from database.
    $donut = ...

    // Looks something like this maybe:
    // $donut = array('id'=>7, 'flavor'=>'chocolate', 'price'=>'1.00')

    $response = $app->response();
    $response['Content-Type'] = 'application/json';
    $response->body(json_encode($donut));
});

W tym miejscu należy zauważyć, że Backbone oczekuje obiektu JSON. Serwer powinien zawsze wskazywać typ zawartości jako „application / json” i zakodować go w formacie json, jeśli możesz. Następnie, gdy Backbone otrzyma obiekt JSON, wie, jak wypełnić model, który go zażądał.

W SLIM PHP trasy działają podobnie jak powyżej.

$app->post('/donut', function() use ($app) {
    // Code to create new donut
    // Returns a full donut resource with ID
});
$app->put('/donut/:id', function($id) use ($app) {
    // Code to update donut with id, $id
    $response = $app->response();
    $response->status(200);  // OK!
    // But you can send back other status like 400 which can trigger an error callback.
});
$app->delete('/donut/:id', function($id) use ($app) {
    // Code to delete donut with id, $id
    // Bye bye resource
});

Więc prawie odbyłeś pełną podróż w obie strony! Idź po napoje gazowane. Lubię Diet Mountain Dew. Kup też dla mnie.

Gdy serwer przetworzy żądanie, zrobi coś z bazą danych i zasobem, przygotuje odpowiedź (bez względu na to, czy będzie to prosty numer statusu http, czy pełny zasób JSON), dane wracają do Backbone w celu ostatecznego przetworzenia.

Za pomocą metod save (), fetch () itp. - możesz dodać opcjonalne wywołania zwrotne w przypadku powodzenia i błędu. Oto przykład, jak ustawiłem ten konkretny tort:

Cake = Backbone.Model.extend({
    defaults: {
        type: 'plain',
        nuts: false
    },
    url: 'cake'
});

myCake = new Cake();
myCake.toJSON()  // Shows us that it is a plain cake without nuts

myCake.save({type:'coconut', nuts:true}, {
    wait:true,
    success:function(model, response) {
        console.log('Successfully saved!');
    },
    error: function(model, error) {
        console.log(model.toJSON());
        console.log('error.responseText');
    }
});

// ASSUME my server is set up to respond with a status(403)
// ASSUME my server responds with string payload saying 'we don't like nuts'

W tym przykładzie jest kilka różnych rzeczy. Zobaczysz, że dla mojego ciasta zamiast ustawiania () ustawiania atrybutów przed zapisaniem, po prostu przekazałem nowe atrybuty do mojego wywołania save. Backbone to niezły ninja w pobieraniu danych JSON z dowolnego miejsca i traktowaniu ich jak mistrz. Więc chcę uratować moje ciasto kokosami i orzechami. (Czy to 2 orzechy?) W każdym razie przekazałem dwa obiekty do mojego zapisu. Atrybuty obiektu JSON ORAZ niektóre opcje. Pierwsza, {czekaj: prawda}, oznacza, że ​​nie aktualizuj mojego modelu po stronie klienta, dopóki podróż po stronie serwera się nie powiedzie. Powodzenie wywołania zwrotnego nastąpi, gdy serwer pomyślnie zwróci odpowiedź. Ponieważ jednak ten przykład skutkuje błędem (status inny niż 200 wskaże Backbone, aby użył wywołania zwrotnego błędu), otrzymujemy reprezentację modelu bez zmian. Powinien być nadal prosty i bez orzechów. Mamy również dostęp do obiektu błędu, który odesłał serwer. Odesłaliśmy ciąg, ale może to być obiekt błędu JSON z większą liczbą właściwości. Znajduje się w atrybucie error.responseText. Tak, „nie lubimy orzechów”.

Gratulacje. Wykonałeś swoją pierwszą całkiem pełną podróż w obie strony od skonfigurowania modelu, zapisania go po stronie serwera iz powrotem. Mam nadzieję, że ta epicka odpowiedź daje Wam POMYSŁ na to, jak to wszystko się łączy. Jest oczywiście wiele szczegółów, które omijam, ale podstawowe pomysły dotyczące zapisywania w Backbone, czasowników RESTful, akcji po stronie serwera, odpowiedzi są tutaj. Kontynuuj przeglądanie dokumentacji Backbone (która jest bardzo łatwa do odczytania w porównaniu z innymi dokumentami), ale pamiętaj, że to zajmuje trochę czasu. Im dłużej będziesz się tym zajmować, tym będziesz bardziej biegły. Każdego dnia uczę się czegoś nowego z Backbone i robi się naprawdę fajnie, gdy zaczynasz robić skoki i widzisz, jak rośnie Twoja płynność w tym frameworku. :-)

Miłego kodowania!

EDYCJA: Zasoby, które mogą być przydatne:

Inne podobne odpowiedzi na SO: Jak wygenerować identyfikatory modeli za pomocą Backbone

Na REST: http://rest.elkstein.org/ http://www.infoq.com/articles/rest-introduction http://www.recessframework.org/page/towards-restful-php-5-basic- wskazówki

jmk2142
źródło
9
Skończyło się na tym, że trochę zwariowałem. Pamiętam, kiedy po raz pierwszy założyłem Backbone i miałem pytania takie jak pytający i trochę za bardzo się bawiłem, pisząc odpowiedź. Jestem pewien, że w pośpiechu popełniłem kilka błędów lub przeoczyłem ważne krytyczne „ah-ha!” więc jeśli tak, daj mi znać. :-P
jmk2142
6
Zdumiewająca odpowiedź, mówiąc co najmniej ... próbuję uchwycić wszystkie wspomniane przez ciebie rzeczy ... sprawa REST wygląda na nieco trudną, chociaż masz rację, na pewno nie możesz mi wyjaśnić REST w tym pytaniu ... ja ' Przejdę przez to ponownie i zaakceptuję to za jakiś czas ... Jeszcze raz
dziękuję
2
Kiedy będę miał czas, zaktualizuję moją odpowiedź o listę dobrych referencji, które mogą pomóc w zadaniu. Nie mogę dać ci drewnianego miecza, aby stawić czoła niebezpiecznemu światu, ale mogę dać ci linki do zasobów stron, które mi pomogły. :-)
jmk2142
5
@testndtv Czy w końcu odpowiedziałem na twoje pytanie? Znak √ byłby mile widziany.
jmk2142
2
Nie ma wątpliwości, że odpowiedziałeś na pytanie w sposób bardziej niż oczekiwany ... Przyjąłem odpowiedź teraz ..
Jeszcze