Angular2中具有不同数据集的可观察数据存储服务

时间:2016-12-29 22:51:43

标签: angularjs angular rxjs

我正在尝试遵循Angular 2中的“Observable data store”模式(详见Angular University的博客文章)据我所知,这意味着,如果我有一个名为{{1的服务我会订阅TodoStore,,以便我可以实时获取待办事项列表的所有最新更新(因为其他组件会添加,删除或修改TodoStore.items$

但是,如果我有两个并排的组件显示不同的Todos列表,在服务器端进行过滤怎么办?有人可能会在今天显示Todo,而另一个则会在用户选择的日期显示Todo到期日。

在这种情况下,我将无法使用相同的Todo,因为两者都将从服务器获取不同的数据。如何在这两个组件之间共享此服务?我的冲动是回到angular1风格的TodoStore服务方法,但后来我将状态存储在单个组件中,并且无法在不进行额外API调用的情况下在多个组件之间共享数据。

1 个答案:

答案 0 :(得分:1)

如果您的列表确实要在服务器端进行过滤,并且您有一个未知数量的同时显示的列表,并且每个列表+过滤器都需要新的服务器请求,那么它是完全有可能使用单个observable(TodoStore.items$)可能不是一个可行的解决方案,也许某种getTodoList(forFilter)可能更容易/更快地实现。

记住:没有“所有案例的完美解决方案。”

但是:即使在这种情况下,您也可以使用商店,这可能是这样的:

interface ITodoListDictionary {
    [key: string]: Todo[];
}

@Injectable()
export class TodoStore {
    todoLists$: BehaviorSubject<ITodoListDictionary> = new BehaviorSubject<ITodoListDictionary>({});

    getListByKey(key: string): Observable<Todo[]> {
        return this.todoLists$
            .pluck(key)
            .distinctUntilChanged() // optional, so you only get the update if there is an actually new list
            .share();
    }

    // this would be called whenever the rest-response for a given list arrives
    setListByKey(key: string, list: Todo[]): void {
        this.todoLists$.take(1)
            .do(dict => {
                const newDict = Object.assign({}, dict, {[key]: list});
                // if you are using TS2.1 you could also use:
                // const newDict = {...dict, {[key]: list}};
                this.todoLists$.next(newDict);
            })
            .subscribe();
    }
}

...在您的模板中,您可以像这样使用它

<todo *ngFor="let todo of todoStore.getListByKey(someKey) | async" todo="todo"></todo>

请注意,很多只是一个可能的解决方案 - 如果没有看到您的实际应用流程,很难说哪个可能是最好的解决方案。