Skip to content

Latest commit

 

History

History
89 lines (73 loc) · 6.33 KB

ns.pattern.model.partial.md

File metadata and controls

89 lines (73 loc) · 6.33 KB

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

Пример задачи 1: список писем. Серверный метод letters отдаёт список кратких описаний писем, а метод letter - подробные данные одного письма.

Пример задачи 2: сбор профиля пользователя из аккаунтов нескольких соц. сетей. Для каждой соц. сети есть отдельный серверный метод получения из неё профиля пользователя.

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

Для того, чтобы в ns совместить в одной модели несколько источников, нужно просто проинициализировать её из первого источника, а затем дополнить данными из второго источника с помощью методов set и setData. При этом, на модели сработают нужные события и виды, зависящие от неё обновятся в момент, предусмотренный используемой схемой обновления.

Пример из жизни: раскрытие подробностей письма в списке

// Модель-коллекция писем
// Запрашивается с сервера и автоматом разделяется
// на отдельные экземпляры модели `letter`.
// В списке приходят краткие представления данных писем
ns.Model.define('letters', {
	split: {
		model_id: 'letter',
		params: {
			id: '.id'
		}
	}
});

// Модель отдельного письма
// Может быть проинициализирована одним из двух способов:
//	1. При автоматическом разделении данных модели `letters` в `letter` будет краткое
//     представление письма.
//	2. При ручном вызове метода `fetch` произойдёт запрос к серверному методу `letter`,
//     в ответ на который ns автоматом подставит в `letter` новые данные - полное 
//     представление письма.
ns.Model.define('letter', {
	params: {
		id: '.id'
	},
	methods: {
		fetch: function() {
			ns.request.models([this]);
		}
	}
});

ns.View.define('letters', {
	models: ['letters'],
	split: {
		view_id: 'letter'
	}
});

ns.View.define('letter', {
	models: ['letter'],
	events: {
		'ns-view-htmlinit': 'onhtmlinit',
		'click .js-expand-letter': 'onExpand'
	},
	methods: {
		onhtmlinit: function() {
			this.getModel('letter').on('ns-model-changed',
				ns.page.go.bind(ns.page, null)
			);
		},
		onExpand: function() {
			this.getModel('letter').fetch();
		}
	}
});

ns.layout.define('main', {
	app: {
		letters: true
	}
});

При начальной отрисовке страницы будет запрошена модель letters. Получив данные, она разделит их на отдельные экземпляры модели letter. На странице появится вид letters, содержащий отдельные виды letter.

При клике на элемент вида letter с классом .js-expand-letter у модели letter будет вызван метод fetch, который сходит на сервер за данными из источника letter и положит их в соответствующий экземпляр модели letter. После этого на модели letter произойдёт событие ns-model-changed, которое заставит страницу перерисоваться.

При повторной отрисовке вида letter в данных его модели уже будет полное представление данных письма, что позволит в шаблоне отрисовать его раскрытым.

Если, например требуется сразу отрисовать список с раскрытым первым письмом, можно доработать серверный метод letters таким образом, чтобы он позволял получать список писем, в котором первое письмо загружено полностью. В итоге список сразу будет отрисован с раскрытым первым элементом.

Эта схема хороша тем, что все данные об экземпляре сущности сервиса (о письме) хранятся в единой модели. Это избавляет от необходимости поддержки и синхронизации избыточного количества сущностей, т.е.

  • логика работы с данными письма собрана в единой модели
  • данные одного экземпляра сущности хранятся в едином экземпляре модели. При удалении и модификации экземпляра на клиенте нужно думать только об одном экземпляре
  • логика отрисовки экземпляра собрана в едином виде