Update list when new item is added

我只是一个虾纸丫 提交于 2019-12-10 12:12:30

问题


Using Angular 7 I have the following service (StackBlitz Example):

@Injectable({
  providedIn: 'root'
})

export class TodoService {

  todos: BehaviorSubject<Todo[]> = new BehaviorSubject([
    { id: 1, title: "Buy book", content: "Buy book about angular" },
    { id: 2, title: "Send invoice", content: "Send invoice to client A" }
  ]);

  public get(): Observable<Todo[]> {
    return this.todos.asObservable();
  }

  public create(todo: Todo) {
    this.todos.next(this.todos.value.concat(todo));
  }

}

This service is used by a few components:

  1. TodoCreateComponent > Creates new todo
  2. TodoListComponent > Shows list of todos
  3. TodoRecentComponent > Shows recent todos

Each component has its own model mapped from a Todo in its own way ...

Some models use many Todo properties (Title, Content), others only one (Title) etc.

On my StackBlitz Example a new Todo is, automatically, added to the todo list:

Objective

Now I need to replace the local data by data taken from an API:

public get(): Observable<Todo[]> {
  return this.httpClient.get<Todo>(`todos`);
}

public create(todo: Todo) {
  const headers = new HttpHeaders({ 'Content-Type': 'application/json' });
  this.httpClient.post(`todos`, todo, { headers: headers });
}

Question

The question is how to integrate HttpClient to get everything in sync:

So when a new Todo is created the list of Todos should be updated ...


回答1:


Use a notification service to tell the list component to repoll the server.

export class RepollTodosNotificationService {

  subject: ReplaySubject<any> = new ReplaySubject();
  obs: Observable<any> = this.subject.asObservable;

  notify = (data: any) => {
    this.subject.next(data)
  }
}

Make service a singleton:

(app.module.ts)

@NgModule({
  providers: [RepollTodosNotificationService]
})

In TodoCreateComponent

this.todoSevice.post(myNewTodo)
     .subscribe(
        result => {
          // current callback code
          this.repollNotifierService.notify(null); // null or data you want to send

In TodoListComponent

export class TodoListComponent implements OnInit, OnDestroy {
    private repollSubscription: Subscription;

    constructor(private repollSvc: RepollTodosNotificationService) {}

    ngOnInit() {
       this.repollSvc.obs.subscribe(() => this.fetchTodos()); // if you transfer data, handle here
    }

    ngOnDestroy() {
        this.subscription.unsubscribe();
    }

    // methods

}



回答2:


One way to stay sync is to update your BehaviorSubject upon the response of your API using the RxJS operator tap, for example:

public get(): Observable<Todo[]> {
  return this.httpClient.get<Todo>(`todos`)
     .pipe(tap(todo => this.todos.next(todos)))
}

or

public create(todo): Observable<Todo[]> {
  return this.httpClient.post<Todo>(`apiUrl`, todo)
     .pipe(tap(todo => // do something with the todo ))
}


来源:https://stackoverflow.com/questions/56116905/update-list-when-new-item-is-added

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!