04.07.2014

JSSDK: Model, Model.List

Почему не Backbone?

Backbone: проблемы

«Целостность»

Backbone vs. Целостность

			// Поиск модели
			function find(id) {
				var model = new XModel({ id: id, flag: false });
				return model.fetch();
			}
			#!+ // Где-то в коде #1
			find(123).then(function (model) {
				model.on("change:flag", function () {  // Слушаем событие
					console.log(model.get("flag"));
				});
			#!- });
			#!+ // Где-то #2
			find(123).then(function (model) {
				#! model.set("flag", true); // и ничего не происходит
			#!- });
		

И не только это

Backbone и Коллекции

			findAll().then(function (collection) {
				#! collection.on("change", function () { });
				#!+ collection
					#! .where({ flag: true })
					#!+ .on("change", function () {
						#! // TypeError: undefined is not a function :[
					#!- })
				#!- ;
				#! // Все методы с коллекцией возвращают массив :[
			});
		

JSSDK: Model

JSSDK: Model

			var Letter = Model.extend({
				#! findUrl: "letters/all",
				#! findOneUrl: "letters/letter",
				#!+ defaults: {
					prev: "",
					next: "",
					subject: "",
					flags: {
						unread: false,
						flagged: false
					}
				#!- }
			});
		

JSSDK: Letter.find

			Letter.find({ folder: 1 }).then(function (models) {
				#! models instanceof Letter.List; // true
				#! models instanceof Letter.List; // true
				#!+ // Получаем список всех id
				#!- var ids = models.pluck("id");
			});
		

JSSDK: Letter.findOne

			Letter.findOne(req.params.id).then(function (model) {
				#!+ if (model.is("flags.unread")) {
					// Письмо непрочитанно, помечаем как прочитанное
					return model.save("flags.unread", false);
				#!- }
			});
		

JSSDK: Model.staticts

JSSDK

			// Есть два месте, где запрашиваем одни и теже данные
			#!+ Promise.all([Model.find(), Model.find()])
				.then(function (results) {
				  #!+ var listA = results[0];
				  #!- var listB = results[1];
				  #!+ log(listA !== listB); // Коллекции разные
				  #!- log(listA[0] === listB[0]); // Но модели одинаковые
			#!- });
		

JSSDK: Model#public

JSSDK: Model и неполные данные

			var Letter = Model.extend({
				url: "/letter/:id/"
			});

			Letter.find().then(function () { // GET /letter/
				Letter.findOne( 123 )  // runtime cache
					.then(function (model) {
						log(model.get("body")); // undefined
					});
			});
		

JSSDK: Model и неполные данные

			var Letter = Model.extend({
				url: "/letter/:id/",
				#!+ isDataFully: function () {
					#! return this.is("body");
				#!- }
			});

			Letter.find().then(function () { // GET /letter/
				#!+ Letter.findOne( 123 )  // GET /letter/123/
					.then(function (model) {
						log(model.get("body")); // "Пару дней назад я познакомился с..."
					#!- });
			});
		

JSSDK: Model & RPC + Storage

			#!+ // Расширяем модель для работы со RPC
			var RPCModel = Model.extend({
				request: RPC
			#!- });
			#!+ // Используем (+ Хранилище)
			var Folder = RPCModel.extend({
				storage: new Storage.Local("folders")
			#!- });
		

JSSDK: Model & RPC

Имеем мульти-источник данных: mailbox/status
{ status: 200, body: { folders: [..], letters: [..] } }
			define(["RPC", "Folder", "Letter"], function (RPC, Folder, Letter) {
				// Export: функция получения статуса ящика
				return function () {
					#!+ return RPC.call("mailbox/status").then(function (req) {
						#!+ return req.map({
							#! folders: Folder,
							#! letters: Letter
						#!- });
					#!- });
				};
			});
		

«Пачка»

Имеем

			Promise.all([
				#! Folder.find(), // получаем все папки
				#! Letter.findOne(123), // получаем письмо по id
				#! Files.find({ letter_id: 123 }) // список файлов для письма
			]).then(function (results) {
				#!+ var folders = results[0];
				var letter = results[1];
				#!- var files = results[2];
			});
		

Улучшаем
Promise.map

Promise.map

— это простая обертка над Promise.all
			#!+ Promise.map({
				#! folders: Folder.find(),
				#! letter: Letter.findOne(123),
				#! files: Files.find({ letter_id: 123 })
			}).then(function (data) {
				#!+ data.folders; // список папок
				data.letter; // письмо
				#!- data.files; // список файлов
			#!- });
		

RPC.batch

Объеденяем запросы в «пачку»

			RPC.batch(function () {
				#!+ return Promise.map({
					folders: Folder.find(),
					letter: Letter.findOne(123),
					files: Files.find({ letter_id: 123 })
				#!- });
			}).then(function (data) {
				#!+ // POST /batch/
				#!- // [{url:"/folders/",data:{}},..]
			});
		

Performance

The End

github.com/RubaXa
@ibnRubaXa