如何在不重新查询服务器的情况下更新可观察数组中的对象?

时间:2016-09-27 18:39:24

标签: angular rxjs angular2-observables

我正在尝试创建用于管理数据的商店,然后在我的组件中使用该商店。 App是使用Ionic2和Angular2构建的。

更新

以下是我对数据存储https://coryrylan.com/blog/angular-2-observable-data-services

进行建模的链接

我遇到的麻烦是更新可观察对象。

这是商店

export class MessageService {
    messages$: Observable<Message[]>;
    update() {
        //...code to make http call and set `this.messages$`
    }
    setMessageFlag(msg: Message) {
        //post to server, nothing more, nothing returned
    }
}

现在我的组件注入了这个服务

export class Inbox OnInit {
    messages$: Observable<Messages[]>

    constructor(private $messageService: MessageService) {
        this.messages$ = this.$messageService.messages$;
    }

    flagMessage(msg: Message) {
        msg.isNew = !msg.isNew;
        this.$messageService.setMessageFlag(msg); //makes a http call to set the message flag
    }

    ngOnInit() {
        this.$messageService.update();
    }
}

然后我的模板使用async管道

来消耗observable
<div *ngFor="let message of messages$ | async">
    <h2 [ngClass]="{'is-read': message.isNew}">{{message.title}}</h2>
    <button (click)="flag(message)">{{message.isNew ? 'Mark as read' : 'Mark as unread'}}</button>
</div>

现在对于我感到困惑的部分。

flagMessage(msg: Message) {
    msg.isNew = !msg.isNew;
    this.$messageService.setMessageFlag(msg);
}

单击该按钮并调用flagMessage(message)方法时,它会设置msg.isNew,并对服务器进行http调用。我看到is-new类应用于<h2>,但随后又快速恢复为原始值。

我不想再次调用从服务器获取所有消息。这似乎效率低下。我认为Observable正在返回副本,但我不确定。

最近这对我来说是一个很好的学习曲线。我已经在上个月内跳到了Angular2,Typescript2,Rxjs和Ionic2,所以任何帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:0)

我认为理想的情况是ReplaySubject,它可以记住最后一个值,并将其重新发送给所有在首次发出值后订阅的观察者。

import {Observable, ReplaySubject} from 'rxjs';

var results = new ReplaySubject(1);

// Simulate HTTP request
Observable.create(subscriber => {
  console.log('Observable.create');
  var data = 'response data';
  results.next(data);
}).subscribe();

results.subscribe(r => console.log(r));
results.subscribe(r => console.log(r));
results.subscribe(r => console.log(r));

// prints to console:
// Observable.create
// response data
// response data
// response data

查看现场演示:http://plnkr.co/edit/DOPsPlMxh06g1lWoJllQ

即使在使用"response data"首次发出results.next(data)之后订阅了三个观察者,他们都会收到相同的数据。

据我了解您的使用案例,您将messages$作为ReplaySubject的实例,因为您订阅了观察者。然后,调用HTTP请求并调用messages$.next(...)的逻辑可以完全独立于它。因此,messages$的所有新订阅者都应收到服务器的最后一个响应,我认为你想要的是什么(?)。