Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

94
Visualizações
Pipe nunca se ejecuta cuando el servidor responde con nuevos datos

Creé una suscripción en mi plantilla para observar cambios en un objeto. La carga inicial del objeto muestra los datos correctos para las tags de propiedad, cuando agrego un elemento a los datos, va a un servidor web y devuelve una lista de todas las tags que están adjuntas al elemento (para mantener el elemento sincronizado). con el servidor). Sin embargo, el elemento recién agregado no se refleja en la página. No estoy 100% seguro de por qué. Creo que se debe a mi instrucción of() pero no estoy seguro. Lo que veo es que zip().pipe() nunca se ejecuta.

¿Necesito usar algo que no sea of ?

Nota: estoy tratando de seguir el patrón declarativo para eliminar el uso de .subscribe()

Nota secundaria: una vez que lo haga funcionar, planeo intentar eliminar la subscribe en esta línea this.server.file().subscribe

apilar

 export interface FileInfo { tags: string[]; } @Component({ selector: 'my-app', template: ` <input #tag /><button (click)="addTag(tag.value)">Add Tag</button> <div *ngIf="data$ | async as data"> <div *ngFor="let tag of data.tags">{{ tag }}</div> </div> `, }) export class AppComponent { data$ = new Observable<FileInfo>(); constructor( // Used to mimic server responses private readonly server: WebServer ) {} ngOnInit() { // I plan on removing this subscribe once I get a grasp on this this.server.file().subscribe((img) => { this.data$ = of(img); }); } addTag(newTag: string) { const data$ = this.server.save(newTag); this.data$.pipe(concatMap((i) => this.zip(data$))); } private zip(tags$: Observable<string[]>) { return zip(this.data$, tags$).pipe( tap((i) => console.log('zipping', i)), map(([img, tags]) => ({ ...img, tags } as FileInfo)) ); } }
about 4 years ago · Juan Pablo Isaza
3 Respostas
Responde à pergunta

0

Estás haciendo mal uso del observable. Después de suscribirse con él, en la plantilla con la canalización asíncrona, no debe actualizar su referencia.

Si necesita actualizar los datos, debe utilizar un Asunto.

 export class AppComponent { private readonly data = new BehaviorSubject<FileInfo>(null); data$ = this.data.asObservable(); constructor( // Used to mimic server responses private readonly server: WebServer ) {} ngOnInit() { this.server.file().subscribe((result) => this.data.next(result)); } addTag(newTag: string) { this.server .save(newTag) .subscribe((tags) => this.data.next({ ...this.data.value, tags })); } }

Además, su servicio podría ser mucho más simple:

 @Injectable({ providedIn: 'root' }) export class WebServer { private readonly tags = ['dog', 'cat']; file(): Observable<FileInfo> { return of({ tags: this.tags }); } save(tag: string) { this.tags.push(tag); return of(this.tags); } }

Aquí está el código de trabajo:

https://stackblitz.com/edit/angular-ivy-my3wlu?file=src/app/app.component.ts

about 4 years ago · Juan Pablo Isaza Relatório

0

Parece que lo que quiere hacer es tener una única fuente observable que emita el último estado de su objeto a medida que se agregan nuevas etiquetas. Luego, simplemente puede suscribirse a este único observable en la plantilla utilizando la canalización asíncrona.

Para lograr esto, puede crear una secuencia dedicada que represente el estado actualizado de las etiquetas de su archivo.

Aquí hay un ejemplo:

 private initialFileState$ = this.service.getFile(); private addTag$ = new Subject<string>(); private updatedfileTags$ = this.addTag$.pipe( concatMap(itemName => this.service.addTag(itemName)) ); public file$ = this.initialFileState$.pipe( switchMap(file => this.updatedfileTags$.pipe( startWith(file.tags), map(tags => ({ ...file, tags })) )) ); constructor(private service: FileService) { } addTag(tagName: string) { this.addTag$.next(itemName); }

Aquí hay una demostración de StackBlitz .

about 4 years ago · Juan Pablo Isaza Relatório

0

Intente convertir completamente webserver.service.ts para proporcionar observables de etiquetas y FileInfo como este:

 import { Injectable } from '@angular/core'; import { concat, Observable, of, Subject } from 'rxjs'; import { delay, map, shareReplay, tap } from 'rxjs/operators'; import { FileInfo } from './app.component'; // best practice is to move this to its own file, btw @Injectable({ providedIn: 'root' }) export class WebServer { private fakeServerTagArray = ['dog', 'cat']; private readonly initialTags$ = of(this.fakeServerTagArray); private readonly tagToSave$: Subject<string> = new Subject(); public readonly tags$: Observable<string[]> = concat( this.initialTags$, this.tagToSave$.pipe( tap(this.fakeServerTagArray.push), delay(100), map(() => this.fakeServerTagArray), shareReplay(1) // performant if more than one thing might listen, useless if only one thing listens ) ); public readonly file$: Observable<FileInfo> = this.tags$.pipe( map(tags => ({tags})), shareReplay(1) // performant if more than one thing might listen, useless if only one thing listens ); save(tag: string): void { this.tagToSave$.next(tag); } }

y ahora su AppComponent puede ser simplemente

 @Component({ selector: 'my-app', template: ` <input #tag /><button (click)="addTag(tag.value)">Add Tag</button> <div *ngIf="server.file$ | async as data"> <div *ngFor="let tag of data.tags">{{ tag }}</div> </div> `, }) export class AppComponent { constructor( private readonly server: WebServer; ) {} addTag(newTag: string) { this.server.save(newTag); } }

Advertencia: si alguna vez llama a WebServer.save mientras WebServer.tags$ o downstream no están suscritos, no pasará nada. En tu caso, no es gran cosa, porque el | async en su plantilla se suscribe. Pero si alguna vez lo divide para guardar una etiqueta en un componente diferente, el servicio deberá modificarse ligeramente para garantizar que la llamada a la API del servidor "guardar nueva etiqueta" todavía se realice.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda