Ответ 1
В основном модели имеют свойство, называемое атрибутами, которые представляют собой различные значения, которые может иметь определенная модель. Магистраль использует объекты JSON как простой способ для заполнения этих значений с использованием различных методов, которые принимают объекты JSON. Пример:
Donuts = Backbone.Model.extend({
defaults: {
flavor: 'Boston Cream', // Some string
price: '0.50' // Dollars
}
});
Чтобы заполнить модель, есть несколько способов сделать это. Например, вы можете настроить экземпляр модели, передав метод JSON OR, называемый 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-запросов. GET и POST. В среде RESTful эти глаголы имеют особое значение для конкретных применений, которые предполагает Backbone. Когда вы хотите получить определенный ресурс с сервера (например, модель пончика, которую я сохранил в прошлый раз, запись в блоге, спецификация компьютера), и этот ресурс существует, вы выполняете запрос GET. И наоборот, когда вы хотите создать новый ресурс, вы используете POST.
До того, как я попал в Backbone, я даже не коснулся следующих двух методов HTTP-запросов. PUT и DELETE. Эти два глагола также имеют конкретное значение для 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 зависит от того, как вы сохраняете его на стороне сервера. Это может быть только идентификатор вашего ресурса donut в таблице базы данных.
Если я создаю PUT для этого URI с новыми данными, я бы обновил его, сохранив его. И если я удалю этот URI, он очистит его от моей системы.
С POST, так как вы еще не создали ресурс, у него не будет установлен идентификатор ресурса. Возможно, целью URI, которую я хочу создать, является просто следующее:
http://localhost:8888/donut
Нет идентификационного фрагмента в URI. Все эти проекты URI зависят от вас и как вы думаете о своих ресурсах. Но в отношении дизайна RESTful я понимаю, что вы хотите сохранить глаголы своих действий в своем HTTP-запросе и ресурсы как существительные, которые делают URI легко читаемыми и удобными для людей.
Вы все еще со мной?: -)
Итак, вернемся к размышлениям о Backbone. Магистраль прекрасна, потому что для вас много работы. Чтобы сохранить наш пончик и secondHelping, мы просто делаем это:
myDonut.save();
mySecondHelping.save();
Магистраль умна. Если вы только что создали ресурс donut, у него не будет ID с сервера. У этого есть что-то, называемое cID, который является тем, что Backbone использует внутренне, но поскольку у него нет официального идентификатора, он знает, что он должен создать новый ресурс, и он отправляет запрос POST. Если у вас есть модель с сервера, у нее, вероятно, будет ID, если все будет правильно. В этом случае при сохранении() 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
Магистраль будет получать третье нажатие на http://localhost:8888/donut/15
Он просто добавит/донит корня вашего сайта.
Если ты ВСЕГДА со мной, хорошо. Я думаю. Если вы не смущены. Но мы все равно будем тащиться. Вторая часть - сторона SERVER. Мы говорили о разных глаголах HTTP и семантических значениях за этими глаголами. Значения, которые вы, базовая, и ваш сервер должны делиться.
Ваш сервер должен понимать разницу между запросами 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, также делают подобные вещи, хотя мне нравятся минимальные. Я сказал, что мне нравится Слим?; -)
Вот что может выглядеть код выдержки на сервере (т.е. конкретно о маршрутах).
$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), тогда данные возвращаются к базовой линии для окончательной обработки.
С помощью методов 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'
В этом примере есть несколько разных вещей. Вы увидите, что для моего торта вместо набора() атрибутов перед сохранением я просто передал новые атрибуты моему вызову сохранения. Магистраль - довольно ниндзя, принимая данные JSON по всему месту и обрабатывая его как чемпион. Поэтому я хочу сохранить свой торт с кокосами и орехами. (Это два ореха?) Во всяком случае, я передал два объекта в свое спасение. Атрибуты JSON object И некоторые параметры. Первый, {wait: true} означает, что мы не обновляем модель клиентской стороны до тех пор, пока серверная поездка не будет успешной. Обратный вызов будет выполняться, когда сервер успешно возвращает ответ. Однако, поскольку этот пример приводит к ошибке (статус, отличный от 200, будет указывать на Backbone для использования обратного вызова ошибки), мы получаем представление модели без изменений. Он должен быть простым и без орехов. У нас также есть доступ к объекту ошибки, который сервер отправил обратно. Мы отправили обратно строку, но это может быть объект ошибки JSON с большим количеством свойств. Это находится в атрибуте error.responseText. Да, нам не нравятся орехи.
Поздравления. Вы сделали свой первый довольно полный раунд от создания модели, сохранив ее на стороне сервера и обратно. Я надеюсь, что этот эпический ответ даст вам ИДЕУ, как все это происходит вместе. Есть, конечно, множество деталей, которые я проезжаю мимо, но основные идеи Backbone save, RESTful глаголы, действия на стороне сервера, ответ здесь. Продолжайте просматривать документацию Backbone (что очень легко читать по сравнению с другими документами), но просто имейте в виду, что для этого требуется время, чтобы обернуть голову. Чем больше вы держите на нем, тем более свободно вы будете. Я каждый день узнаю что-то новое с Backbone, и мне становится очень весело, когда вы начинаете прыгать и видите, как быстро развивается эта инфраструктура.: -)
Счастливое кодирование!
EDIT: Ресурсы, которые могут быть полезны:
Другие похожие ответы на SO: Как сгенерировать идентификаторы модели с помощью базовой линии
В REST: http://rest.elkstein.org/ http://www.infoq.com/articles/rest-introduction http://www.recessframework.org/page/towards-restful-php-5-basic-tips