Skip to content

Latest commit

 

History

History
104 lines (84 loc) · 6.27 KB

ns.pattern.model.state.md

File metadata and controls

104 lines (84 loc) · 6.27 KB

Состояние интерфейса в noscript можно хранить одним из двух основных способов:

  • в url, который затем преобразуется в параметры
  • в данных модели.

Первый способ является основным и базовым. С его помощью формируется множество адресов сервиса, т.е. его внешний api.

Этот способ обладает следующими особенностями:

  • он физически способен вместить очень ограниченное число атрибутов состояния
  • при перезагрузке страницы он остаётся неизменным
  • каждый атрибут, добавленный в url фактически добавляется во внешний api web-сервиса, что не всегда хорошо.

Эти особенности делают url непригодным для хранения

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

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

Модель состояния - это обычная модель. В простейшем случае она локальная, инициализируется данными на клиенте и никогда не запрашивается с сервера. Она добавляется в зависимость вида, состояние которого она должна хранить. Её значения устанавливаются в runtime в методах видов и других моделях. При перезагрузке страницы модель создаётся заново и состояние сбрасывается.

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

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

Пример. Модель состояния элемента списка

	ns.Model.define('letters', {
		split: {
			model_id: 'letter',
			items: 'letter',
			params: {
				id: '.id'
			}
		}
	});

	ns.Model.define('letter', {
		params: {
			id: null
		}
	});

	ns.Model.define('stateLetter', {
	    events: {
	        // записываем данные в модель при создании
	        'ns-model-init': function() {
                this.setData({selected: false});
            }
	    },
	    methods: {
	        toggleSelected: function() {
    	        if (this.get('.selected')) {
                    this.set('.selected', false);
                } else {
                    this.set('.selected', true);
                }
            }
	    }
		params: {
			id: null
		}
	});

Определена модель-коллекция letters, которая при загрузке автоматически порождает какое-то количество моделей letter. Опраделена модель stateLetter (состояние письма), которая зависит от тех же параметров, что и letter.

Модель stateLetter инициализирует свои данные при создании.

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

	ns.View.define('letter', {
		models: {
			'letter': true,
			'stateLetter': 'keepValid'
		},
		events: {
			'click .js-select-letter': 'toggleSelected'
		},
		methods: {
			toggleSelected: function() {
				this.getModel('stateLetter').toggleSelected();
			}
		}
	});

Определён вид-коллекция letters, который по модели letters создаёт внутри себя виды letter. Каждый вид letter зависит от моделей letter и stateLetter.

При наступлении события click на dom-элементе .js-select-letter срабатывает метод toggleSelected, который изменяет модель состояния. Если dom-элемент .js-select-letter - checkbox, то при клике перерисовывать вид letter уже не нужно. Поэтому в зависимости вида letter от модели stateLetter указан метод keepValid, предотвращающий его перерисовку.

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