Tengo un problema: "Cuando se presiona el mouse, se crea un rectángulo, se cambia el tamaño cuando se mueve y se completa cuando se levanta el mouse". Traté de usar rxjs, pero no es realmente una buena solución:
import { scan, mergeMap, takeUntil, fromEvent } from 'rxjs'; const mouseDown$ = fromEvent(document, 'mousedown'); const mouseUp$ = fromEvent(document, 'mouseup'); const mouseMove$ = fromEvent(document, 'mousemove'); function createNode() { const node = document.createElement('DIV'); node.setAttribute('style', 'position: absolute; border: 1px solid red;'); document.body.appendChild(node); return node; } mouseDown$ .pipe( mergeMap(() => { return mouseMove$.pipe( takeUntil(mouseUp$), scan((node, e: MouseEvent) => { if (!node) { let x = null; x = createNode(); x.style.top = `${e.clientY}px`; x.style.left = `${e.clientX}px`; return x; } else { node.style.bottom = `${e.clientY}px`; node.style.right = `${e.clientX}px`; } return node; }, null) ); }) ) .subscribe(() => {});El problema es que los efectos secundarios se agregan al método "escanear". ¿Tiene una solución mucho mejor para este problema?
Si desea evitar un efecto secundario de tubería interna (lo que en general es algo bueno), puede dividir su lógica en dos Observables/Subscriptions diferentes:
Crear nodo observable
let node = null const createNode$ = mouseDown$.pipe( switchMapTo(mouseMove$.pipe( takeUntil(mouseUp$), take(1) )) ) createNode$.subscribe(createNode) function createNode(e: MouseEvent) { const node = document.createElement('DIV'); node.setAttribute('style', 'position: absolute; border: 1px solid red;'); document.body.appendChild(node); x.style.top = `${e.clientY}px`; x.style.left = `${e.clientX}px`; return node; }Actualizar nodo observable
const updateNode$ = mouseDown$.pipe( switchMapTo(mouseMove$.pipe( takeUntil(mouseUp$), skip(1) )) ) updateNode$.subscribe(updateNode(node)) function updateNode(node: Node) { return function(e: MouseEvent) { node.style.bottom = `${e.clientY}px`; node.style.right = `${e.clientX}px`; } }No prefiero el anterior a su solución: ambos son iguales en mi opinión. Es solo una forma de evitar posibles efectos secundarios. Hay varias opiniones sobre cuándo y por qué evitar los efectos secundarios. Personalmente, trato de reducirlos tanto como puedo, pero hay algunos escenarios en los que simplemente no vale la pena hacerlo (o es posible que no haya visto una buena solución).
Una vez hice una pregunta sobre cuándo-debo-crear-una-nueva-suscripción-para-un-efecto-secundario-específico . La respuesta puede brindarle algunos detalles sobre cuándo y por qué puede ser útil para evitar efectos secundarios.