Rxjs: Behavior Subject emite valor sin llamar a next ()

Oct 05 2020

Estoy creando un filtro de selección múltiple con RxJs y usando un servicio angular para comunicar valores entre componentes.

@Injectable({
    providedIn: 'root'
  })
export class SomeService{

    private readonly defaulFilterSelect: SomeSelect[] = 
    [
      {
          id: 1,
          label: 'label 1',
          options: [
              { id: 2, isChecked: false},
              { id: 3, isChecked: false}
          ]
      },
      {
          id: 7,
          label: 'Label 2',
          type: { name: 'checkbox' },
          options: [
              { id: 4, isChecked: false},
              { id: 5, isChecked: false}
          ]
      }
    ]

    private filterSelectDataSource = new BehaviorSubject<SomeSelect[]>(this.defaulFilterSelect);

    filterSelectData$ = this.filterSelectDataSource.asObservable();

    public get getFilterSelectData(){
      return this.filterSelectDataSource.value;
    }
}

El caso es que, cuando un usuario hace algún trabajo en la aplicación, la propiedad isCheckedde la SomeSelectclase puede volverse verdadera, y luego el usuario tiene la posibilidad de regresar al estado inicial donde estaban todas las propiedades llamadas "isChecked" false. Así que pensé ... bueno, si necesito que mi observable vuelva al estado inicial, ¿por qué no solo next()mi valor inicial predeterminado?defaulFilterSelect

    uncheckAllOptions(){
      this.filterSelectDataSource.next(this.defaulFilterSelect); //here
  }

Por alguna razón, esto no funciona como esperaría, y cuando inicio sesión en la consola en una suscripción, obtengo el valor anterior de mi observable. Además, si this.filterSelectDataSource.valuemodifico el objeto , sin llamar, next(obj)la interfaz de usuario escucha los cambios y los renderiza, lo cual es realmente confuso para mí, ya que espero que solo la llamada this.filterSelectDataSource.next(someNewObject);desencadene cambios en la interfaz de usuario que consuman ese observable. ¿Alguien puede señalarme la dirección correcta aquí? ¡Gracias!

Respuestas

2 RobertDempsey Oct 05 2020 at 17:33

Debe realizar una clonación profunda defaulFilterSelectcuando lo establezca como su valor inicial filterSelectDataSource, de lo contrario, cuando lo actualice, estará actualizando la misma referencia de defaulFilterSelect.

La forma de clonar en profundidad depende de usted, pero generalmente uso Lodash cloneDeep.