defi.js Object.defineProperty рдкрд░ рдЖрдзрд╛рд░рд┐рдд рдПрдХ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛рд╢реАрд▓ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ

defi.js

defi.js рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдХ рджрд░реНрдЬрди рдлрд╝рдВрдХреНрд╢рдВрд╕ рд╢рд╛рдорд┐рд▓ рд╣реИрдВ рдЬреЛ рдЧреЗрдЯрд░реНрд╕ рдФрд░ рд╕реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рднреА рдЬрд╛рд╡рд╛рд╕реНрдХреНрд░рд┐рдкреНрдЯ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рджрд┐рд▓рдЪрд╕реНрдк рд╕реБрд╡рд┐рдзрд╛рдПрдБ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВред


рдзреНрдпрд╛рди Gif (3.5MB)
рдХреЛрд╖


рд╣реИрд▓реЛ рд╡рд░реНрд▓реНрдб рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдо рдкрд╣рд▓реЗ рдирд╛рдо, рдЕрдВрддрд┐рдо рдирд╛рдо рдФрд░ рдЧреНрд░реАрдЯрд┐рдВрдЧ ( рдбреЗрдореЛ ) рдХреНрд╖реЗрддреНрд░ рд╕реЗ рдорд┐рд▓рдХрд░ рдПрдХ рдЫреЛрдЯрд╛ рд╡рд┐рдЬреЗрдЯ рдмрдирд╛рддреЗ рд╣реИрдВред


<input class="first"> <input class="last"> <output class="greeting"></output> 

 //    const obj = { first: 'John', last: 'Doe' }; //     first  last //   ,      defi.on(obj, 'change:first', () => console.log('First name is changed')); defi.on(obj, 'change:last', () => console.log('Last name is changed')); //    ( greeting)  , //  first  last  defi.calc(obj, 'greeting', ['first', 'last'], (first, last) => `Hello, ${first} ${last}`); //      //      defi.bindNode(obj, { first: '.first', last: '.last', greeting: '.greeting' }); 

рдирддреАрдЬрддрди, рдпрджрд┐ first рдпрд╛ last рдмрджрд▓рд╛рд╡ рд╣реБрдЖ рд╣реИ, рддреЛ рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдХрдВрд╕реЛрд▓ рдХреЛ рд░рд┐рдкреЛрд░реНрдЯ рдХрд░рддреЗ рд╣реИрдВ, greeting рдкреНрд░реЙрдкрд░реНрдЯреА рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЕрдкрдбреЗрдЯ рд╣реЛ рдЬрд╛рддреА рд╣реИ, рдФрд░ рдЗрд╕рдХреЗ рддрддреНрд╡ рдХреЛ рдПрдХ рдирдпрд╛ рдорд╛рди рдорд┐рд▓рддрд╛ рд╣реИ (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, "рд╣реИрд▓реЛ, рдЬреЙрди рдбреЛ")ред рдРрд╕рд╛ рд╣рд░ рдмрд╛рд░ рд╣реЛрддрд╛ рд╣реИ рдЬрдм рдЧреБрдг рдмрджрд▓рддреЗ рд╣реИрдВ, рдФрд░ рдЗрд╕рд╕реЗ рдХреЛрдИ рдлрд░реНрдХ рдирд╣реАрдВ рдкрдбрд╝рддрд╛ рдХрд┐ рдХреИрд╕реЗред рдЖрдк рдХреЛрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдорд╛рди рд╕реЗрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ obj.first = 'Jane' , рдпрд╛ рдлрд╝реАрд▓реНрдб рдХрд╛ рдорд╛рди рдмрджрд▓рдХрд░, рдФрд░ рдЕрдиреНрдп рд╕рднреА рдкрд░рд┐рд╡рд░реНрддрди рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдШрдЯрд┐рдд рд╣реЛрдВрдЧреЗред


рдорд╛рдорд▓реЗ рдореЗрдВ рд╡рд╕реНрддреБ рдХреА рд╕рдВрдкрддреНрддрд┐ рдФрд░ рдордирдорд╛рдиреЗ рдврдВрдЧ рд╕реЗ HTML рддрддреНрд╡ (рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рд╣рдордиреЗ output рдЯреИрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ) рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЛ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, bindNode рддрдерд╛рдХрдерд┐рдд "рдмрд╛рдЗрдВрдбрд░" рдХреЛ рдмрд╛рдЗрдВрдбреЛрдб рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЬреЛ рдЬрд╝рд┐рдореНрдореЗрджрд╛рд░ рд╣реИ рдХрд┐ рддрддреНрд╡ рдХреА рд╕реНрдерд┐рддрд┐ рдФрд░ рдСрдмреНрдЬреЗрдХреНрдЯ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЛ рдХреИрд╕реЗ рд╕рд┐рдВрдХреНрд░рдирд╛рдЗрдЬрд╝ рдХрд┐рдпрд╛ рдЬрд╛рдПред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, bindNode рдХреЛ рдкрддрд╛ рдирд╣реАрдВ рд╣реИ рдХрд┐ рдХреИрд╕реЗ рдиреЛрдбреНрд╕ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╣реИ рдЬреЛ рдлрд╛рд░реНрдо рддрддреНрд╡ рдирд╣реАрдВ рд╣реИрдВред


 const htmlBinder = { setValue: (value, binding) => binding.node.innerHTML = value, }; //   obj.greeting  innerHTML   defi.bindNode(obj, 'greeting', '.greeting', htmlBinder) 

рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЖрдк рд╕рд╛рдорд╛рдиреНрдп-рдмрд╛рдЗрдВрдбрд░реНрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ html рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ (рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп-рдЙрджреНрджреЗрд╢реНрдп рдмрд╛рдЗрдВрдбрд░реЛрдВ рдХрд╛ рдПрдХ рд╕рдВрдЧреНрд░рд╣ рд╣реИ)ред


 const { html } = require('common-binders'); //   obj.greeting  innerHTML   defi.bindNode(obj, 'greeting', '.greeting', html()) 

рдПрдкреАрдЖрдИ рддрд░реАрдХреЗ


рд╕рднреА рддрд░реАрдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рд╕реНрддреГрдд рджрд╕реНрддрд╛рд╡реЗрдЬ, рдЙрдкрд▓рдмреНрдз рдХреЙрд▓ рд╡рд┐рд╡рд┐рдзрддрд╛рдПрдВ, рдЭрдВрдбреЗ, рдЖрджрд┐ defi.js.org рдкрд░ рджреЗрдЦреЗ рдЬрд╛ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рд╣реИ рдХрд┐ рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рддрд░реАрдХреЛрдВ рдХреЗ рдЕрд▓рд╛рд╡рд╛, defi.js рдореЗрдВ рд░реВрдЯрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреБрд╕реНрддрдХрд╛рд▓рдп рд╣реИ: рдбрд┐рдлрд╝рд╛рдЗ -рд░рд╛рдЙрдЯрд░ ред


  • bindNode - рджреЛ-рддрд░рдлрд╝рд╛ рдмрд╛рдЗрдВрдбрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рдПрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░реЙрдкрд░реНрдЯреА рдФрд░ рдПрдХ DOM рдиреЛрдб рдмрд╛рдБрдзрддрд╛ рд╣реИ ред

 //   // (  HTML5  , . defaultBunders) defi.bindNode(obj, 'myKey', '.my-element'); //   defi.bindNode(obj, 'myKey', '.my-element', { // ,      // (    -DOM ) on: 'click', //     ? getValue: ({ node }) => someLibraryGetValue(node), //       ? setValue: (v, { node }) => someLibrarySetValue(node, v), //    (  )? //      //  'initialize'     initialize: ({ node }) => someLibraryInit(node), }); obj.myKey = 'some value'; //   

  • рдХреИрд▓реНрдХ - рдЕрдиреНрдп рдЧреБрдгреЛрдВ рдкрд░ рдПрдХ рд╡рд╕реНрддреБ рдХреА рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдХреА рдирд┐рд░реНрднрд░рддрд╛ рдмрдирд╛рддрд╛ рд╣реИ (рдЕрдиреНрдп рд╡рд╕реНрддреБрдУрдВ рд╕реЗ рднреА)ред

 defi.calc(obj, 'a', ['b', 'c'], (b, c) => b + c); obj.b = 1; obj.c = 2; console.log(obj.a); // 3 

  • рдордзреНрдпрд╕реНрдерддрд╛ - рдЬрдм рдпрд╣ рдмрджрд▓рддрд╛ рд╣реИ рддреЛ рдПрдХ рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдореВрд▓реНрдп рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░рддрд╛ рд╣реИред

 defi.mediate(obj, 'x', value => String(value)); obj.x = 1; console.log(obj.x); // "1" console.log(typeof obj.x); // "string" 

  • рдСрди - рдПрдХ рдЗрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдкреНрд░рд▓реЗрдЦрди рд╕рд╛рдЗрдЯ рдкрд░ рдПрдХ рдЫреЛрдЯрд╛ рд▓реЗрдЦ рд╣реИ рдЬреЛ рд╕рднреА рд╕рдВрднрд╛рд╡рд┐рдд рдШрдЯрдирд╛рдУрдВ рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред

 defi.on(obj, 'change:x', () => { alert(`obj.x now equals ${obj.x}`); }); obj.x = 1; 

  • рдмрдВрдж - рдПрдХ рдШрдЯрдирд╛ рд╣реИрдВрдбрд▓рд░ рд╣рдЯрд╛рддрд╛ рд╣реИред

 defi.off(obj, 'change:x bind'); 


 defi.on(obj, 'foo bar', (a, b, c) => { alert(a + b + c); }); defi.trigger(obj, 'foo', 1, 2, 3); //  alert(6) 

  • unbindNode - рдиреЛрдб рдХреЗ рддрддреНрд╡ рдФрд░ DOM рдХреЗ рдмрдВрдзрди рдХреЛ рдирд┐рд╖реНрдХреНрд░рд┐рдп рдХрд░рддрд╛ рд╣реИред

 defi.bindNode(obj, 'myKey', '.my-element'); defi.unbindNode(obj, 'myKey', '.my-element'); 

  • рдмрд╛рдзреНрдп - рджреА рдЧрдИ рд╕рдВрдкрддреНрддрд┐ рд╕реЗ рдЬреБрдбрд╝реЗ DOM рддрддреНрд╡ рдХреЛ рд▓реМрдЯрд╛рддрд╛ рд╣реИред

 defi.bindNode(obj, 'myKey', '.my-element'); const node = defi.bound(obj, 'myKey'); //  document.querySelector('.my-element') 


 defi.chain(obj) .calc('a', 'b', b => b * 2) .set('b', 3) .bindNode('c', '.node'); 

  • defaultBinder - рд╕рдВрдмрдВрдзрд┐рдд рдмрд╛рдЗрдВрдбрд░ рдпрд╛ рдЕрдкрд░рд┐рднрд╛рд╖рд┐рдд рд╡рд╛рдкрд╕ рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрд╛рд░реНрдпреЛрдВ рдХреА рдПрдХ рд╕рд░рдгреАред рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдПрдХ рдмрд╛рдЗрдВрдбрд░ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдП рдмрд┐рдирд╛ рдХрд╕реНрдЯрдо рддрддреНрд╡реЛрдВ рдФрд░ рдЧреБрдгреЛрдВ рдХреЛ рдмрд╛рдВрдзрдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред

 defi.defaultBinders.unshift(element => { //      "foo" if(element.classList.contains('foo')) { // ,     return { on: ..., getValue: ..., setValue: ... }; } }); // ... defi.bindNode(obj, 'myKey', '.foo.bar'); 

  • LookForBinder - рдЕрдЧрд░ defaultBinders рдлрд╝рдВрдХреНрд╢рди рдПрдХ рдореЗрдВ рд╕реЗ рдПрдХ рд╡рд╛рдкрд╕ рдЖрдП рддреЛ рддрддреНрд╡ рдХреЗ рдЕрдиреБрд░реВрдк рдмрд╛рдЗрдВрдбрд░ рд▓реМрдЯрд╛рддрд╛ рд╣реИред

 const element = document.createElement('input'); element.type = 'text'; console.log(defi.lookForBinder(element)); 

  • рдирд┐рдХрд╛рд▓реЗрдВ - рдПрдХ рд╡рд╕реНрддреБ рд╕рдВрдкрддреНрддрд┐ рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рдШрдЯрдирд╛ рд╕рдВрдЪрд╛рд▓рдХреЛрдВ рдХреЛ рд╣рдЯрд╛рддрд╛ рд╣реИред

 defi.remove(obj, 'myKey'); 

  • рд╕реЗрдЯ - рд╡рд╕реНрддреБ рдХреА рд╕рдВрдкрддреНрддрд┐ рдХреЛ рд╕реЗрдЯрд░ рдХреА рддрд░рд╣ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди change:KEY рд▓рд┐рдП рдХреБрдЫ рдбреЗрдЯрд╛ рдкрд╛рд╕ рдХрд░рдирд╛ рд╕рдВрднрд╡ рдмрдирд╛рддрд╛ рд╣реИ change:KEY рдИрд╡реЗрдВрдЯ рд╣реИрдВрдбрд▓рд░ред рдЖрдк рд╕рдВрдкрддреНрддрд┐ рдореВрд▓реНрдп рдХреА рд╕реЗрдЯрд┐рдВрдЧ рдХреЛ "рдЪреБрдк" рднреА рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЕрд░реНрдерд╛рдд, рдХреЙрд▓ рдХреЛ рдХреЙрд▓ рди рдХрд░реЗрдВ change:KEY рдмрд┐рд▓реНрдХреБрд▓ рднреАред

 defi.set(obj, 'myKey', 3, { silent: true }); 



defi.js Matreshka.js рдлреНрд░реЗрдорд╡рд░реНрдХ рдХрд╛ рдПрдХ рд╕рдВрд╢реЛрдзрд┐рдд рдФрд░ рд╕рд░рд▓реАрдХреГрдд рдХрдард┐рди рдХрд╛рдВрдЯрд╛ рд╣реИ, рдЬрд┐рд╕рдореЗрдВ рд░реЗрдВрдбрд░рд┐рдВрдЧ рдПрд░реЗ, рдХрдИ рдХрдХреНрд╖рд╛рдПрдВ, рдФрд░ рдЕрдзрд┐рдХ рд╡рд┐рдзрд┐рдпрд╛рдВ рд╢рд╛рдорд┐рд▓ рд╣реИрдВред рдХреБрдЫ рд╡рд┐рдзрд┐рдпрд╛рдБ рдЬреЛ рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдбрд┐рдлреАрдЬрд╝ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреА рд╣реИрдВред рдЕрдиреНрдп рддрд░реАрдХреЛрдВ рдХреЗ рд▓рд┐рдП рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЗ рд╕рд╛рде рдкреНрд░рддрд┐рд╕реНрдерд╛рдкрд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, once рдФрд░ onDebounce рдмрдЬрд╛рдп onDebounce рдЖрдк once: true рдкрд╛рд╕ рдХрд░рдХреЗ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ once: true рдпрд╛ debounce: number рд╡рд┐рдХрд▓реНрдкред


рдЕрдВрдд рддрдХ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред рдЖрдкрдХрд╛ рджрд┐рди рд╢реБрдн рд╣реЛ

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


All Articles