• Jobs
  • About Us
  • professionals
    • Home
    • Jobs
    • Courses and challenges
  • business
    • Home
    • Post vacancy
    • Our process
    • Pricing
    • Assessments
    • Payroll
    • Blog
    • Sales
    • Salary Calculator

0

225
Views
BehaviorSubject: mutación del valor actual entre suscripciones

Supongamos que tengo BehaviorSubject con interfaz de usuario:

 interface User { firstName: string; lastName: string; } let user: User = { firstName: 'Cuong', lastName: 'Le', }; let bs = new BehaviorSubject<User>(user);

Hay dos suscripciones, sub1 intentó cambiar el nombre. Sub2 se suscribe más tarde y el objeto de usuario también ha cambiado de nombre, ya que sub1 lo cambió antes:

 let sub1 = bs.subscribe((u) => { u.firstName = 'An'; console.log(u); }); let sub2 = bs.subscribe((u) => { console.log(u); });

es difícil depurar cuando este caso ocurre en una gran aplicación Angular. ¿Cómo hacemos que el valor sea inmutable al suscribirse?

Estoy buscando una solución inmutable profunda para evitar que el código en otro lugar cambie los datos en lugar de la sombra

almost 3 years ago · Juan Pablo Isaza
3 answers
Answer question

0

Usar esta respuesta y envolver su tipo en este tipo de utilidad inmutable debería resolver su problema. A diferencia de la palabra clave de solo lectura o el tipo de utilidad de solo lectura, la interfaz inmutable en esta respuesta hará que todas las propiedades sean de solo lectura de forma recursiva.

 interface User { firstName: string; lastName: string; address: { street: string; } } let user: User = { firstName: 'Cuong', lastName: 'Le', address: { street: '123 Sesame St.' } }; let bs = new BehaviorSubject<Immutable<User>>(user); let sub1 = bs.subscribe((u) => { u.address.street = '456'; //<-- Cannot assign to 'street' because it is a read-only property. console.log(u); });
almost 3 years ago · Juan Pablo Isaza Report

0

Puede usar el tipo de utilidad Readonly<T> para marcar el tipo en el BehaviorSubject como Readonly<User> en lugar de User :

 let bs = new BehaviorSubject<Readonly<User>>(user);

Ahora, TS le avisará cuando intente modificar:

captura de pantalla

No se puede asignar a 'firstName' porque es una propiedad de solo lectura. (2540)

almost 3 years ago · Juan Pablo Isaza Report

0

Este es un problema que he tenido que resolver varias veces. Siempre que pase objetos simples no circulares a través del sujeto, esta solución debería funcionar.

El único requisito es que utilice la biblioteca lodash , que admite una copia profunda muy rápida (sin copias de referencia). He buscado por todas partes y todavía tengo que encontrar uno que sea más rápido.

 let bs = (new BehaviorSubject<User>(user)).pipe( map((userData) => _.cloneDeep(userData)) );

Lo he usado en objetos de estado bastante grandes y siempre me ha impresionado la rapidez con la que puede realizar copias. La implicación aquí es que cualquier emisión que salga del sujeto es una copia del original, por lo que los cambios ocurren de forma aislada y nunca podrán volver a la fuente.

almost 3 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Our process Sales
Legal
Terms and conditions Privacy policy
© 2025 PeakU Inc. All Rights Reserved.

Andres GPT

Recommend me some offers
I have an error