我偶然发现了这个Plunkr http://plnkr.co/edit/yMBoVkxohwhPig5COgkU?p=preview
它显示了一个可观察的数据服务。我的问题所在的部分显示:
export class TodoService {
private _todos$: Subject<Todo[]>;
private baseUrl: string;
private dataStore: {
todos: Todo[]
};
constructor(private http: Http) {
this.baseUrl = 'http://56e05c3213da80110013eba3.mockapi.io/api';
this.dataStore = { todos: [] };
this._todos$ = <Subject<Todo[]>>new Subject();
}
get todos$() {
return this._todos$.asObservable();
}
loadAll() {
this.http.get(`${this.baseUrl}/todos`).map(response => response.json()).subscribe(data => {
this.dataStore.todos = data;
this._todos$.next(this.dataStore.todos);
}, error => console.log('Could not load todos.'));
}
上面的代码运行正常。但是,当我使用不进行http调用的代码替换loadAll
时:
loadAll() {
this.dataStore.todos = [{ 'id': '1', 'createdOn': 1472831416, 'value': 'value 1' }, { 'id': '2', 'createdOn': 1472831360, 'value': 'value 2' }, { 'id': '4', 'createdOn': 1472831771, 'value': 'value 4' }, { 'id': '5', 'createdOn': 1472831716, 'value': 'value 5' }, { 'id': '6', 'createdOn': 1472831658, 'value': 'value 6' }];
this._todos$.next(this.dataStore.todos);
}
它停止通知前端,如此Plunkr所示:http://plnkr.co/edit/ObiWt2cm6sGSgW2Hf5ya?p=preview
有人可以解释为什么会这样,以及如何让它发挥作用?
答案 0 :(得分:2)
Subject
期望将一个项目传递给它,而不是项目数组。你在做什么类似于:
let subject = new Subject<{ message: string }>();
subject.onNext([{ message: 'test one' }, { message: 'test two' }]);
这是错误,应该在编译时生成错误。
正如我所提到的,onNext
期望一个项的泛型类型,而不是项目数组。所以这样的事情是正确的:
let subject = new Subject<{ message: string }>();
subject.onNext({ message: 'test one' });
如果要从数组中的项创建observable
,您有几个选项,第一个是遍历数组并为数组中的每个项调用onNext
,如所以:
let subject = new Subject<{ message: string }>();
let items = [{ message: 'test one' }, { message: 'test two'}];
items.forEach(item => subject.onNext(item));
另一种方法是从数组中创建一个observable:
let subject = new Subject<{ message: string }>();
let items = [{ message: 'test one' }, { message: 'test two'}];
let itemsObservable = Observable.from(items);
在此示例中,itemObservable
将替换您的:
get todos$() {
return this._todos$.asObservable();
}
并成为:
get todos$() {
return this.itemObservable;
}
希望这能解决一些问题。解决方案中的基本问题基本上是您误解了Subject
的工作原理。