Как сохранить данные модели Backbone.js?


86

Я больше увлекаюсь фронтенд-разработкой и недавно начал использовать Backbone.js в своем приложении. Я хочу сохранить данные модели на сервере.

Не могли бы вы объяснить мне различные способы сохранения данных модели (с использованием формата json). Я использую Java на стороне сервера. Также я в основном видел, как REST используется для сохранения данных. Поскольку я больше увлекаюсь фронтенд-разработкой, я не знаю о REST и других подобных вещах.

Было бы здорово, если бы кто-нибудь мог объяснить мне процесс на простом примере.

Ответы:


272

В основном модели имеют свойство, называемое атрибутами, которое представляет собой различные значения, которые может иметь определенная модель. Backbone использует объекты JSON как простой способ заполнить эти значения с помощью различных методов, которые принимают объекты JSON. Пример:

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

Чтобы заполнить модель, есть несколько способов сделать это. Например, вы можете настроить экземпляр модели, передав метод JSON ИЛИ используйте метод set (), который принимает объект атрибутов JSON.

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'}

Итак, это подводит нас к сохранению моделей и сохранению их на сервере. Существует множество деталей относительно «Что такое REST / RESTful?» И объяснить все это в короткой аннотации здесь как-то сложно. В частности, что касается сохранения REST и Backbone, то вам стоит поразмыслить над семантикой HTTP-запросов и тем, что вы делаете со своими данными.

Вы, вероятно, привыкли к двум типам HTTP-запросов. ПОЛУЧИТЬ и ОТПРАВИТЬ. В среде RESTful эти глаголы имеют особое значение для определенных применений, которые предполагает Backbone. Если вы хотите получить определенный ресурс с сервера (например, модель пончика, которую я сохранил в прошлый раз, запись в блоге, спецификацию компьютера) и этот ресурс существует, вы выполняете запрос GET. И наоборот, когда вы хотите создать новый ресурс, вы используете POST.

До того, как я попал в Backbone, я даже не касался следующих двух методов HTTP-запросов. ПОСТАВИТЬ и УДАЛИТЬ. Эти два глагола также имеют особое значение для Backbone. Если вы хотите обновить ресурс (например, изменить вкус лимонного пончика на лимонный пончик и т. Д.), Вы используете запрос PUT. Если вы хотите удалить эту модель с сервера полностью, вы используете запрос DELETE.

Эти основы очень важны, потому что с вашим приложением RESTful у вас, вероятно, будет обозначение URI, которое будет выполнять соответствующую задачу в зависимости от типа используемой команды запроса. Например:

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

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

Если я сделаю GET для этого URI, он получит модель пончика с идентификатором 17.: id зависит от того, как вы сохраняете его на стороне сервера. Это может быть просто идентификатор вашего пончика в таблице базы данных.

Если я сделаю PUT в этот URI с новыми данными, я буду обновлять его, сохраняя поверх него. И если я УДАЛЯЮ этот URI, он удалит его из моей системы.

С помощью POST, поскольку вы еще не создали ресурс, у него не будет установленного идентификатора ресурса. Возможно, цель URI, которую я хочу создать, будет просто такой:

http://localhost:8888/donut

В URI нет фрагмента идентификатора. Все эти конструкции URI зависят от вас и от того, как вы относитесь к своим ресурсам. Но что касается дизайна RESTful, я понимаю, что вы хотите сохранить глаголы своих действий в своем HTTP-запросе и ресурсы в виде существительных, которые делают URI легкими для чтения и удобными для человека.

Ты все еще со мной? :-)

Итак, давайте вернемся к Backbone. Backbone прекрасен, потому что делает за вас много работы. Чтобы сохранить пончик и второй помощник, мы просто делаем это:

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

Магистраль умная. Если вы только что создали ресурс пончика, у него не будет идентификатора с сервера. У него есть так называемый cID, который Backbone использует для внутренних целей, но, поскольку у него нет официального идентификатора, он знает, что должен создать новый ресурс, и отправляет запрос POST. Если вы получили свою модель с сервера, у нее, вероятно, будет идентификатор, если все в порядке. В этом случае, когда вы save () Backbone предполагает, что вы хотите обновить сервер, он отправит PUT. Чтобы получить конкретный ресурс, вы должны использовать метод Backbone .fetch (), который отправляет запрос GET. Когда вы вызываете .destroy () для модели, она отправляет DELETE.

В предыдущих примерах я никогда явно не указывал Backbone, где находится URI. Сделаем это в следующем примере.

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 ПОЛУЧИТ третью помощь. http://localhost:8888/donut/15Он просто добавит / пончиковый стержень в корень вашего сайта.

Если ты ЕЩЕ со мной, хорошо. Я думаю. Если только вы не запутались. Но мы все равно будем тащиться. Вторая часть - это СЕРВЕР. Мы говорили о различных глаголах HTTP и семантических значениях этих глаголов. Значения, которые должны разделять вы, Backbone и ваш сервер.

Ваш сервер должен понимать разницу между запросами GET, POST, PUT и DELETE. Как вы видели в приведенных выше примерах, все GET, PUT и DELETE могут указывать на один и тот же URI http://localhost:8888/donut/07Если ваш сервер не может различать эти HTTP-запросы, он будет очень запутан относительно того, что делать с этим ресурсом.

Это когда вы начинаете думать о коде конца сервера RESTful. Кому-то нравится Ruby, кому-то нравится .net, мне нравится PHP. Особенно мне нравится микросхема SLIM PHP. SLIM PHP - это микро-фреймворк, который имеет очень элегантный и простой набор инструментов для работы с RESTful-действиями. Вы можете определять маршруты (URI), как в примерах выше, и в зависимости от того, является ли вызов GET, POST, PUT или DELETE, он выполнит правильный код. Есть и другие решения, похожие на SLIM, такие как Recess, Tonic. Я считаю, что более крупные фреймворки, такие как Cake и CodeIgniter, также делают похожие вещи, хотя мне нравится минимализм. Я сказал, что люблю Slim? ;-)

Это то, что может выглядеть фрагмент кода на сервере (т.е. конкретно в отношении маршрутов).

$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));
});

Здесь важно отметить, что Backbone ожидает объект JSON. Ваш сервер всегда должен указывать тип содержимого как «application / json» и кодировать его в формате json, если можете. Затем, когда Backbone получает объект JSON, он знает, как заполнить модель, которая его запросила.

В SLIM PHP маршруты работают примерно так же, как описано выше.

$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
});

Итак, вы почти прошли весь путь туда и обратно! Иди купи газировку. Мне нравится Diet Mountain Dew. Купи мне тоже.

После того, как ваш сервер обработает запрос, сделает что-то с базой данных и ресурсом, подготовит ответ (будь то простой номер статуса http или полный ресурс JSON), данные возвращаются в Backbone для окончательной обработки.

С помощью методов save (), fetch () и т. Д. Вы можете добавить дополнительные обратные вызовы в случае успеха или ошибки. Вот пример того, как я приготовил именно этот торт:

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'

В этом примере есть несколько разных моментов. Вы увидите, что для моего торта вместо set () атрибутов перед сохранением я просто передал новые атрибуты моему вызову сохранения. Backbone - настоящий ниндзя, когда собирает данные JSON повсюду и обрабатывает их как чемпион. Итак, я хочу сохранить свой торт с кокосами и орехами. (Это 2 ореха?) Так или иначе, я передал два объекта в свое сохранение. Атрибуты объекта JSON И некоторые параметры. Первое, {wait: true} означает, что не обновлять мою клиентскую модель, пока отключение на стороне сервера не будет успешным. Успешный обратный вызов произойдет, когда сервер успешно вернет ответ. Однако, поскольку этот пример приводит к ошибке (статус, отличный от 200, указывает Backbone использовать обратный вызов ошибки), мы получаем представление модели без изменений. Он все равно должен быть простым и без орехов. У нас также есть доступ к объекту ошибки, который сервер отправил обратно. Мы отправили обратно строку, но это может быть объект ошибки JSON с дополнительными свойствами. Он находится в атрибуте error.responseText. Да, «мы не любим орехи».

Поздравляю. Вы совершили свой первый довольно полный путь туда и обратно: от настройки модели, сохранения ее на стороне сервера и обратно. Я надеюсь, что этот эпический ответ даст вам представление о том, как все это сочетается. Конечно, я прохожу мимо множества деталей, но основные идеи сохранения Backbone, RESTful-глаголов, серверных действий, Response здесь. Продолжайте изучать документацию по Backbone (которую очень легко читать по сравнению с другими документами), но помните, что это займет время, чтобы осознать. Чем больше вы усвоите, тем более свободно вы будете говорить. Я узнаю что-то новое с Backbone каждый день, и это становится действительно забавным, когда вы начинаете делать прыжки и видите, как ваше владение этой структурой растет. :-)

Удачного кодирования!

РЕДАКТИРОВАТЬ: ресурсы, которые могут быть полезны:

Другие похожие ответы на SO: как сгенерировать идентификаторы модели с помощью Backbone

В REST: http://rest.elkstein.org/ http://www.infoq.com/articles/rest-introduction http://www.recessframework.org/page/towards-restful-php-5-basic- чаевые


9
В итоге я немного помешался на этом. Я помню, когда я впервые запустил Backbone, у меня были такие вопросы, как у автора вопроса, и мне было слишком весело писать ответ. Я уверен, что в спешке сделал несколько ошибок или пропустил важное критическое «ага!» фасеты, так что если я это сделаю, дайте мне знать. :-P
jmk2142

6
Сногсшибательный ответ, мягко говоря ... я пытаюсь понять все вещи, упомянутые вами ... вещь REST выглядит немного сложной, хотя вы правы, вы, конечно, не можете объяснить мне REST в этом вопросе ... Я ' Я снова
пройдусь

2
Когда у меня будет время, я дополню свой ответ списком хороших рекомендаций, которые могут помочь вам в поиске. Я не могу дать вам деревянный меч, чтобы противостоять опасному миру, но могу дать вам ссылки на ресурсы, которые помогли мне. :-)
jmk2142

5
@testndtv Я ответил на ваш вопрос? Знак √ будет оценен по достоинству.
jmk2142

2
Нет сомнений в том, что ты ответил на вопрос более, чем ожидалось ... Я принял ответ сейчас ... Еще раз большое спасибо за помощь ...
testndtv
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.