defi.js es una biblioteca reactiva basada en Object.defineProperty

defi.js

defi.js es una biblioteca que incluye una docena de funciones que agregan características interesantes a cualquier objeto JavaScript usando getters y setters.


Atención GIF (3.5MB)
Repositorio


Como Hello World, cree un pequeño widget compuesto por un campo de nombre, apellido y saludo ( demo ).


<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' }); 

Como resultado, si el first o el last cambiado, los controladores de eventos informan esto a la consola, la propiedad de greeting se actualiza automáticamente y su elemento obtiene un nuevo valor (por defecto, "Hola, John Doe"). Esto sucede cada vez que cambian las propiedades, y no importa cómo. Puede establecer el valor usando el código obj.first = 'Jane' , o cambiando el valor del campo, y todos los demás cambios ocurrirán automáticamente.


En caso de que sea necesario sincronizar las propiedades del objeto y el innerHTML un elemento HTML arbitrario (en el ejemplo usamos la etiqueta de output ), necesitamos pasar el llamado "aglutinante" a la función bindNode, que es responsable de cómo sincronizar el estado del elemento y las propiedades del objeto. Por defecto, bindNode no sabe cómo trabajar con nodos que no son elementos de formulario.


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

Además, puede usar html de la biblioteca de carpetas comunes (esta es una colección de carpetas de propósito general).


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

Métodos API


Puede encontrar documentación detallada para todos los métodos, variaciones de llamadas disponibles, marcas , etc. en defi.js.org . Vale la pena mencionar que, además de los métodos a continuación, defi.js tiene una biblioteca para enrutamiento: defi-router .


  • bindNode : enlaza una propiedad de objeto y un nodo DOM para el enlace bidireccional.

 //   // (  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'; //   

  • calc : crea una dependencia de una propiedad de un objeto en otras propiedades (incluso de otros objetos).

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

  • mediate - Modifica el valor de una propiedad cuando cambia.

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

  • on : agrega un controlador de eventos. Hay un pequeño artículo en el sitio de documentación que describe todos los eventos posibles.

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

  • off : elimina un controlador de eventos.

 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 : deshabilita el enlace del elemento y el DOM del nodo.

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

  • obligado - Devuelve el elemento DOM asociado con la propiedad dada.

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

  • chain : se utiliza para encadenar funciones defi.js.

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

  • defaultBinders : una matriz de funciones que devuelve el cuaderno correspondiente o indefinido. Permite que bindNode enlace elementos y propiedades personalizados sin especificar explícitamente un cuaderno.

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

  • lookForBinder : devuelve el cuaderno correspondiente al elemento si una de las funciones defaultBinders devolvió uno.

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

  • remove : elimina una propiedad de objeto y controladores de eventos asociados.

 defi.remove(obj, 'myKey'); 

  • set : establece la propiedad del objeto, como el setter, pero permite pasar algunos datos al change:KEY controlador de eventos change:KEY . También puede hacer que la configuración del valor de la propiedad sea "silenciosa", es decir, no llame al change:KEY en absoluto.

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



defi.js es una bifurcación rígida revisada y simplificada del marco Matreshka.js, que incluía matrices de representación, varias clases y más métodos. Algunos métodos que podrían entrar en defi.js se han reemplazado con opciones para otros métodos, por ejemplo, en lugar de once y onDebounce puede usar el método on pasando las opciones de debounce: number once: true o debounce: number .


Gracias por leer hasta el final. Que tengas un buen día.

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


All Articles