Class . This is a slightly modified version of the function I wrote about on the javascript.ru forum ( link to the dock ). window.MK = window.Matreshka = Class({ ... }); var MyClass = Class({ constructor: function() { ... } }); ... which then returns from the Class function. If the constructor is not defined, then it will be an empty function.MyClass inherited from Nested Doll): var MyClass = Class({ 'extends': MK }); 'extends' quotes are needed not only to avoid syntax errors (extends is a reserved word), but also to highlight the syntax. Other properties can be without quotes.).initMK method must be called .initMK , which, in this case, initializes the pseudo- __id properties: __id (instance id for internal use), the .__events object (event object), and the .__special object (storing values ​​of "special" properties, their accessories and associated elements). The same rule is true for classes, which will be explained in the following articles: MK.Array and MK.Object . <form class="login-form"> <input type="text" class="user-name" placeholder="Username"> <input type="password" class="password" placeholder="Password"> <label> <input type="checkbox" class="show-password"> Show Password </label> <input type="submit" value="Sign In" class="submit"> <label> <input type="checkbox" placeholder="Password" class="remember-me"> Remember me </label> </form> (Here, I removed the extra blocks and classes that are responsible only for a nice appearance, the resulting example uses Bootstrap).LoginForm . In my work, I stick to the rule: one class per one complex element (form, widget ...). Now LoginForm will be the only class in our tiny application. var LoginForm = Class( ... ); var LoginForm = Class({ 'extends': MK }); var LoginForm = Class({ 'extends': MK, constructor: function() { this.initMK(); // "" } }); .bindings . This is a matter of taste and you can, without any problems, bind elements in the constructor (but only after calling .initMK ). ... bindings: function() { return this // (. (1)) // , , .innerHTML , // , .bindNode( this, '.login-form' ) // (on, getValue, setValue), // .bindNode({ userName: this.$( '.user-name' ), // , 'keyup' password: this.$( '.password' ), // , 'keyup' showPassword: this.$( '.show-password' ), // , 'click' rememberMe: this.$( '.remember-me' ), // , 'click' }) .bindNode( 'isValid', this.$( '.submit' ), { // (. (2)) setValue: function( v ) { $( this ).toggleClass( 'disabled', !v ); } }) ; }, ... ".bindNode( this, '.login-form' )" mean? If the current instance is passed as the first argument in .bindNode , the Matryoshka actually binds the special property "__this__" . This means that the record this.bindNode( this, '.login-form' ); this.bindNode( '__this__', '.login-form' ); "__this__" ? In order to use the method .$ , which allows you to set the context of the bound elements (sandbox). This binding is optional but desirable. With it and using the .$ method, you can avoid theoretical conflicts binding the same element in different classes..$ : Http://finom.imtqy.com/matreshka/docs/Matreshka.html#$this.$( '.submit' ) element to the 'isValid' property (which will be described below) in the following way: if isValid == false , then add the 'disabled' class to this element, if not, remove this class. .bindNode( 'isValid', this.$( '.submit' ), { setValue: function( v ) { $( this ).toggleClass( 'disabled', !v ); } }) .bindNode( 'isValid', this.$( '.submit' ), MK.binders.className( '!disabled' ) ) this . The .bindNode method, like many other methods (.set, .defineGetter ...), does just that. In addition, I took as a rule the design of blocks of chained calls: ( ) [].1() [].2() ... [].N() ( ) .bindings to the constructor: ... constructor: function() { this .initMK() .bindings() // .initMK() ; }, ... .events . ... events: function() { this.boundAll().on( 'submit', function( evt ) { // (. (1)) this.login(); evt.preventDefault(); }.bind( this ) ); // (. (2)) return this // "showPassword" (. (3)) .on( 'change:showPassword', function() { this.bound( 'password' ).type = this.showPassword ? 'text' : 'password'; }, true ) // "userName" "password" (. (4)) .on( 'change:userName change:password', function() { this.isValid = this.userName.length >= 4 && this.password.length >= 5; }, true ) ; }, ... this or '__this__' ), or rather its jQuery instance, and call the jQuery.fn.on method with the 'submit' event..boundAll method: http://finom.imtqy.com/matreshka/docs/Matreshka.html#boundAllevent.target , event.delegatedTarget , so I easily event.delegatedTarget standard context. this.boundAll().on( 'submit', function() { ... }.bind( this ) ); this.boundAll( 'key' ).on( 'click', function() { ... }.bind( this ) ); this.on( 'submit::__this__', function() { ... }); this.on( 'click::key', function() { ... }); .on method (with a value of true ). This is not the context of the handler (since the type is boolean ), this argument tells us that the handler should be run immediately, immediately after the declaration (that is, you do not need to call .trigger )."userName" or "password" properties, we set the 'isValid' property to true or false , checking the length of the login and password. ... constructor: function() { this .initMK() .bindings() .events() ; }, ... ... login: function() { var data; if( this.isValid ) { data = { userName: this.userName, password: this.password, rememberMe: this.rememberMe }; alert( JSON.stringify( data ) ); } return this; } ... var loginForm = new LoginForm(); var LoginForm = Class({ 'extends': MK, rememberMe: true, constructor: function() { this .initMK() .bindings() .events() ; }, bindings: function() { return this .bindNode( this, '.login-form' ) .bindNode({ userName: this.$( '.user-name' ), password: this.$( '.password' ), showPassword: this.$( '.show-password' ), rememberMe: this.$( '.remember-me' ) }) .bindNode( 'isValid', this.$( '.submit' ), { setValue: function( v ) { $( this ).toggleClass( 'disabled', !v ); } }) ; }, events: function() { this.boundAll().on( 'submit', function( evt ) { this.login(); evt.preventDefault(); }.bind( this ) ); return this .on( 'change:showPassword', function() { this.bound( 'password' ).type = this.showPassword ? 'text' : 'password'; }, true ) .on( 'change:userName change:password', function() { this.isValid = this.userName.length >= 4 && this.password.length >= 5; }, true ) ; }, login: function() { var data; if( this.isValid ) { data = { userName: this.userName, password: this.password, rememberMe: this.rememberMe }; alert( JSON.stringify( data ) ); } return this; } }); var loginForm = new LoginForm(); .login method. data = { userName: this.userName, password: this.password, rememberMe: this.rememberMe }; MK.Object .Source: https://habr.com/ru/post/200078/
All Articles