📜 ⬆️ ⬇️

Router for Matreshka.js 2

Demo
Repository


tl; dr


The plugin includes the synchronization of the properties of the object and a piece of URL.


Matreshka.initRouter(object, '/a/b/c/'); object.a = 'foo'; object.b = 'bar'; object.c = 'baz' // location.hash  #!/foo/bar/baz/ 

To use the History API instead of location.hash , you need to pass the string "history" second argument.


 Matreshka.initRouter(object, '/a/b/c/', 'history'); 

Import CJS module:


 const initRouter = require('matreshka-router'); initRouter(object, '/a/b/c/', 'history'); 



How does “traditional” routing work? The developer specifies the rule (route) and describes how the application will behave when the URL corresponds to the specified rule.


 route('books/:id', id => { //  - }); 

Matreshka Router works differently. The library synchronizes part of the path with the property of the object.


Disclaimer: this way of routing may not cover all those tasks that are usually put in front of a regular router. Use an alternative solution if you need it.


The principle of the plug-in is as follows: you specify which part of the URL (both hash and HTML5 History are supported) synchronized with the property.


Let's say you want to synchronize the property "x" with the first part of location.hash , the property "y" with the second.


 Matreshka.initRouter(object, "/x/y/"); 

Now when you write ..


 object.x = 'foo'; object.y = 'bar'; 

... The hash will automatically change to #!/foo/bar/


And vice versa, if you manually, programmatically or with the help of the “forward” and “back” arrows change the address, the properties will change automatically.


 location.hash = '#!/baz/qux/'; // ...    console.log(object.x, object.y); // 'bar', 'qux' 

As always, you can listen to properties using the on method.


 Matreshka.on(object, 'change:x', handler); //  ,   -  Matreshka: this.on('change:x', handler); 

initRouter can pass a string with asterisks to the initRouter function to ignore part of the URL.


 Matreshka.initRouter(object, '/x/*/y'); 

If the hash looks like #!/foo/bar/baz/ , then object.x becomes equal to "foo" , object.y - "baz" .


This feature is useful when one class controls one part of the address, another - the other.


class1.js


 Matreshka.initRouter(this, '/x/*/'); 

class2.js


 Matreshka.initRouter(this, '/*/y/'); 

It is important to remember two things:


1. If the property has a true value when the router is initialized, the address will change immediately after calling initRouter . Otherwise, on the contrary, the property will receive the value of the path part.


 object.x = 'foo'; Matreshka.initRouter(object, '/x/y/'); 

2. If the property specified in the route gets a false value, all subsequent properties specified in the route will be null .


 Matreshka.initRouter(object, '/x/y/z/u/'); object.y = null; //  object.z  object.u   null 

The idea is to keep the url state and properties relevant. It would be strange to have the property "z" with the value "foo" provided there is no part of the address associated with this property.


HTML5 History API


In addition to hash routing, the plugin supports the ability to work with HTML5 History. For initialization, you need to pass an additional type parameter equal to "history" to the initRoute method (by default, type = "hash" ).


 Matreshka.initRouter(object, '/x/y/z/', 'history'); 

Additional Information


The core of the router is implemented as a class Matreshka.Router . Its constructor takes one argument: the type of the router ("hash" , "history" or an arbitrary string).


When the router is connected, two instances of the Matreshka.Router class are created with the hash and history types, which are stored, respectively, in Matreshka.Router.hash and Matreshka.Router.history (lazy initialization is used, so the connection does nothing without using it). For these two instances, the singleton pattern is implemented, that is, when creating a router with the hash type, Matreshka.Router.hash returned instead of creating a new instance. Such a logic centralizes the processing of the URL, having a positive effect on performance and does not cause collisions. Objects, in turn, simply subscribe to changes and do not parse.


"Custom" instances of Matreshka.Router can be created manually, in case you need to generate a link for further arbitrary use. In this case, changing the properties will not affect the hash and will not cause pushState .


Instances of the Router class have three properties.


path is a property that contains the current URL, for example, /foo/bar/baz/ .


hashPath is a property that burns a path, with a hashbang added to it, for example #!/foo/bar/baz/


parts is a property represented as an array containing actual pieces of the path, for example, ['foo', 'bar', 'baz'] .


All three properties are declared using the calc method, so when changing one property, the others change:


 Matreshka.Router.hash.path = '/yo/man/'; 

... And two methods


subscribe(object, route) - signs the object for changes in properties.


init() is used for lazy initialization when calling subscribe (there is no need to call manually).


 const customRouter = new Matreshka.Router('myType'); const object = { a: 'foo', b: 'bar' }; customRouter.subscribe(object, '/a/b/'); console.log(customRouter.path); // /foo/bar/ 

Import CommonJS Module


Everything described above concerns a non-modular environment. If the application is in the CommonJS environment (NodeJS, Webpack, Rollup ...), connecting the matreshka-router module does not add new static properties to the Matreshka class. Instead, initRouter imported in the traditional way.


 const initRouter = require('matreshka-router'); initRouter(object, '/x/y/'); 

You can import the Router class like this:


 const Router = require('matreshka-router/router'); const customRouter = new Router('myType'); 

All good.


')

Source: https://habr.com/ru/post/277171/


All Articles