Состояние интерфейса в 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
.