Демо
Репозиторий
Плагин включает синхронизацию свойств объекта и куска урла.
Для использования History API вместо
Справедливо предположить, что то, что называется фронт-енд фреймворком должно включать в себя возможность роутинга. Вопрос “есть ли в Матрешке роутер” звучит достаточно часто, на что всегда был один ответ: есть много замечательных библиотек, которые имплементируют роутинг и они будут работать луше, чем непопулярная реализация “местячкового” роутера. Этот вопрос пришлось добавить в скромный FAQ со ссылкой на одну из самых популярных библиотек для роутинга Director. Но время пришло.
Как работает “традиционный” роутинг? Разработчик указывает правило (роут) и описывает то, как будет себя вести приложение при соответствии урла с указанным правилом.
Matreshka Router работает совсем по-другому. Он следует традициям Матрешки, синхронизируя часть пути со свойством объекта.
Дисклеймер: такой способ роутинга совершенно нов и беспрецедентен. Он может не покрывать все те задачи, которые обычно ставят перед обычным роутером. Поэтому, воспользуйтесь альтернативным решением, если в этом есть необходимость.
Принцип работы плагина в следующем: вы указываете какая часть урла (поддерживается и hash, и HTML5 History) синхронизируется со свойством.
Скажем, вы хотите синхронизировать свойство
Теперь когда вы пишете..
… Хеш автоматически изменится на
И наоборот, если вы вручную, программно или с помощью стрелок “вперед” и “назад“ меняете адрес, свойства изменятся автоматически.
Как и всегда, свойства можно прослушивать с помощью метода on.
В метод
Если хеш выглядит, как
Такая возможность полезна тогда, когда один класс контролирует одну часть адреса, другой — другую.
class1.js
class2.js
Важно помнить две вещи:
1. Если при инициализации роутера свойство имеет правдивое значение, адрес изменится сразу после вызова
2. Если свойство, указанное в роуте получит лживое значение, все последующие свойства, указанные в роуте, получат значение
Пускай вас не пугает такое решение. Идея в том, чтоб поддерживать состояния урла и свойств актуалными. Было бы странно иметь свойство
Кроме хеш роутинга, плагин поддерживает возможность работы с HTML5 History. Для инициализации нужно передать в метод
Напомню, что почти все методы Матрешки (для связывания, реактивности, событий и пр.) имеют свой статичный аналог, в качестве примера приведу метод on.
Подобные статичные методы скрыты под флажком “продвинутый режим” в документации.
Такое разделение не обошло стороной и этот плагин: кроме метода прототипа, в наличии есть и статичный аналог метода
Ядро роутера реализовано в виде класса
При подключении модуля создаётся два экземпляра класса
"Кастомные" экземпляры
Экземпляры класса
Все три свойства объявлены с помощью метода linkProps, так что при изменении одного свойства, меняются и другие:
… И два метода
Всем добра.
Репозиторий
tl;dr
Плагин включает синхронизацию свойств объекта и куска урла.
this.initRouter('/a/b/c/');
this.a = 'foo';
this.b = 'bar';
this.c = 'baz'
// location.hash теперь #!/foo/bar/baz/
Для использования History API вместо
location.hash
, нужно передать строку "history"
вторым аргументом.this.initRouter('/a/b/c/', 'history');
Справедливо предположить, что то, что называется фронт-енд фреймворком должно включать в себя возможность роутинга. Вопрос “есть ли в Матрешке роутер” звучит достаточно часто, на что всегда был один ответ: есть много замечательных библиотек, которые имплементируют роутинг и они будут работать луше, чем непопулярная реализация “местячкового” роутера. Этот вопрос пришлось добавить в скромный FAQ со ссылкой на одну из самых популярных библиотек для роутинга Director. Но время пришло.
Как работает “традиционный” роутинг? Разработчик указывает правило (роут) и описывает то, как будет себя вести приложение при соответствии урла с указанным правилом.
route('books/:id', id => {
// делать что-то
});
Matreshka Router работает совсем по-другому. Он следует традициям Матрешки, синхронизируя часть пути со свойством объекта.
Дисклеймер: такой способ роутинга совершенно нов и беспрецедентен. Он может не покрывать все те задачи, которые обычно ставят перед обычным роутером. Поэтому, воспользуйтесь альтернативным решением, если в этом есть необходимость.
Принцип работы плагина в следующем: вы указываете какая часть урла (поддерживается и hash, и HTML5 History) синхронизируется со свойством.
Скажем, вы хотите синхронизировать свойство
"x"
с первой частью location.hash
, свойство "y"
— со второй.this.initRouter("/x/y/");
Теперь когда вы пишете..
this.x = 'foo';
this.y = 'bar';
… Хеш автоматически изменится на
#!/foo/bar/
И наоборот, если вы вручную, программно или с помощью стрелок “вперед” и “назад“ меняете адрес, свойства изменятся автоматически.
location.hash = '#!/baz/qux/';
console.log(this.x, this.y); // ‘bar’, ‘qux’
Как и всегда, свойства можно прослушивать с помощью метода on.
this.on('change:x', handler);
В метод
initRouter
можно передать строку со “звездочками”, если нет необходимости в синхронизации какой-нибудь части урла.this.initRouter('/x/*/y');
Если хеш выглядит, как
#!/foo/bar/baz/
, то this.x
становится равным "foo"
, this.y
— "baz"
.Такая возможность полезна тогда, когда один класс контролирует одну часть адреса, другой — другую.
class1.js
this.initRouter('/x/*/');
class2.js
this.initRouter('/*/y/');
Важно помнить две вещи:
1. Если при инициализации роутера свойство имеет правдивое значение, адрес изменится сразу после вызова
initRouter
. Иначе — наоборот, свойство получит значение части пути.this.x = 'foo';
this.initRouter('/x/y/');
2. Если свойство, указанное в роуте получит лживое значение, все последующие свойства, указанные в роуте, получат значение
null
.this.initRouter('/x/y/z/u/');
this.y = null; // уствновит this.z и this.u тоже в null
Пускай вас не пугает такое решение. Идея в том, чтоб поддерживать состояния урла и свойств актуалными. Было бы странно иметь свойство
"z"
со значением "foo"
при условии отсутствующей части адреса, связанной с этим свойством.HTML5 History API
Кроме хеш роутинга, плагин поддерживает возможность работы с HTML5 History. Для инициализации нужно передать в метод
initRoute
дополнительный параметр type
равный "history"
(по умолчанию, type = "hash"
).this.initRouter('/x/y/z/', 'history');
Поддержка произвольных объектов
Напомню, что почти все методы Матрешки (для связывания, реактивности, событий и пр.) имеют свой статичный аналог, в качестве примера приведу метод on.
// если this - инстанс Матрешки
this.on('something', handler);
// для любого другого объекта
var obj = {};
MK.on(obj, 'something', handler);
Подобные статичные методы скрыты под флажком “продвинутый режим” в документации.
Такое разделение не обошло стороной и этот плагин: кроме метода прототипа, в наличии есть и статичный аналог метода
initRouter
, который принимает произвольный объект в качестве первого аргумента и позволяет синхронизировать части адреса со свойствами обычного объекта.var obj = {};
MK.initRouter(obj, '/a/b/c/');
obj.a = 'foo';
obj.b = 'bar';
obj.c = 'baz';
Дополнительная информация
Ядро роутера реализовано в виде класса
Matreshka.Router
. Его конструктор принимает один аргумент: тип роутера ("hash"
, "history"
или произвольную строку).При подключении модуля создаётся два экземпляра класса
Matreshka.Router
с типами hash
и history
, которые хранятся, соответственно, в Matreshka.Router.hash
и Matreshka.Router.history
(используется ленивая инициализация, поэтому подключение модуля без его использования ничего не делает). Для этих двух экземпляров реализуется паттерн синглтон, т. е, при создании роутера с типом hash
возвращается Matreshka.Router.hash
вместо создания нового экземпляра. Такая логика централизует обработку урла, положительно влияя на производительность и не вызывает коллизии. Объекты, в свою очередь, просто подписываются на изменения и не занимаются парсингом."Кастомные" экземпляры
Matreshka.Router
могут быть созданы вручную, на случай, если есть наобходимость работать вне браузерного окружения, или нужно сгенерировать ссылку для дальнейшего произвольного использования. В этом случае, изменение свойств не повлияет ни на hash
и не вызовет pushState
.Экземпляры класса
Router
имеют три свойства.path
— свойство, которое содержит актуальный урл, например, /foo/bar/baz/
.hashPath
— свойство, которое сожеджит path, с дописанным к ней hashbang, например #!/foo/bar/baz/
parts
— свойство, представленное в виде массива, содержащее актуальные кусочки пути, например, [‘foo’, ‘bar’, ‘baz’]
.Все три свойства объявлены с помощью метода linkProps, так что при изменении одного свойства, меняются и другие:
Matreshka.Router.hash.path = '/yo/man/';
… И два метода
subscribe(object, route)
— подписывает объект на изменения в свойствах.init()
— используется для ленивой инициализации при вызове subscribe
(вызывать вручную нет нужды).var customRouter = new Matreshka.Router(),
object = {
a: 'foo',
b: 'bar'
};
customRouter.subscribe(object, '/a/b/');
console.log(customRouter.path); // /foo/bar/
Всем добра.