Observable的变化未反映在View中

时间:2016-09-26 12:42:28

标签: angular rxjs

我基本上遵循this guide来实现Observable数据服务。

在商店类(ItemsStore)中,我的BehaviorSubject包含商品列表

items:BehaviorSubject<List<Item>> = new BehaviorSubject(List([]));

组件在模板中使用该存储,如下所示:

<ion-slide *ngFor="let item of itemStore.items | async" >
  [...]
</ion-slide>

现在这可以在应用加载时正常工作 - 显示我的所有项目。但是,如果我使用商店类中的以下代码向BehaviorSubject添加项目:

this.items.next(this.item.getValue().push(newItem));

这不会反映在视图中。我的印象是,变更处理是由angular2自动完成的,但情况似乎并非如此。

如何检测和处理此类更改,以便它们反映在视图中?

3 个答案:

答案 0 :(得分:2)

我怀疑问题与你打电话的方式有关:

this.items.next(this.item.getValue().push(newItem));

我不知道this.item.getValue()会返回什么,但如果push()方法与Array.push()相同,则会返回新的长度(重要的是它不会返回附加了新项目的this.items

async管道定义为:

  

异步管道订阅Observable或Promise并返回它已发出的最新值

因此,当您调用this.items.next(...)时,异步管道只接收新长度,并尝试使用*ngFor进行迭代。

如果this.item占有<List<Item>>,那么您可能想要致电:

this.item.getValue().push(newItem);
this.items.next(this.item);

顺便说一句,asObservable()方法用于隐藏您使用Subject的事实。主题让您拨打next()complete(),这是您不希望其他用户惹麻烦的事情。出于这个原因,最好只传递Observable,并且只为自己保留Subject

答案 1 :(得分:1)

items属性应该是Observable,但是您将其设置为BehaviourSubject类型。在您的链接中有:

@Injectable()
export class TodoStore {
    private _todos: BehaviorSubject<List<Todo>> = new BehaviorSubject(List([]));

    public todos: Observable<List<Todo>> = this._todos.asObservable();

    constructor(private todoBackendService: TodoBackendService) {
        this.loadInitialData();
    }
    ...
}

所以假设你遵循本教程,你应该这样做:

private _items: BehaviorSubject<List<Item>> = new BehaviorSubject(List([]));
public items: Observable<List<Item>> = this._items.asObservable();

答案 2 :(得分:1)

解决了 - 这是一个非常愚蠢的错误 - 对我感到羞耻。 ItemsStore被注入两个不同的类中,并且由于依赖注入为每次注入创建了一个实例 - 那么我们有两个相同类型的应该只有一个。

将依赖项(ItemsStore)移动到全局提供程序数组解决了这个问题。