H,我在正确使用rxJs observable方面遇到了问题。我的要求是将所有聊天室都放在一本书上(如果房间不可用则创建一个新的聊天室) 我使用下面的代码,聊天组件中的observable永远不会被调用。
我的聊天组件
@Component({
selector: 'chat',
templateUrl: './chat.component.html'
})
export class ChatComponent implements OnInit {
this.selectbookStream.subscribe(bookId=>
{
this.chatService.getRooms(book id)
.subscribe(rooms => {
console.log("in chat component");
console.log(rooms);
this.rooms = rooms;
});
})
}
我的聊天服务
@Injectable()
export class ChatService {
public getRooms(bookID) {
console.log("in get rooms")
return this.thisPartyChatService.createRooms(bookID).map(r=>r)
}
}
ThirdParty聊天服务
public createRooms(bookID: string): Observable<any> {
let rooms = [];
this.modelService.getBookDetails(bookID).subscribe(book=> {
this.getRoom(book.name).subscribe(r => {
if (Object.keys(r).length === 0) {
rooms.push( this.createRoom(book.name).map(res=>res))
} else {
// rooms.push(Observ)
rooms.push(Observable.of({
'id': r.id,
'type': r.type,
'title': r.title,
'name': r.title,
'created': r.created
})
)
}
})
});
return Observable.forkjoin(rooms);
}
public createRoom(bookID: string): Observable<any> {
return this.http.post(this.apiUrl.room, { 'title': bookID, 'teamId':
teamId }, this.generateHeader()).map(res => res.json);
}
public getRoom(modelId: string): Observable<any> {
this.roomTitle = modelId;
// search all rooms in CISCO sparck and match with modelId
return this.http.get(this.apiUrl.room, this.generateHeader())
.map(this.findRoom);
}
private findRoom(res: Response) {
let body = res.json();
let room: any;
body.items.forEach(element => {
if (element.title == this.roomTitle)
return element;
});
return {};
}
答案 0 :(得分:1)
我认为问题出在createRooms()
方法的结构中。基本上你有以下几点:
public createRooms(bookID: string): Observable<any> {
let rooms = [];
this.modelService.getBookDetails(bookID).subscribe(book => {
this.getRoom(book.name).subscribe(...);
})
return Observable.forkjoin(rooms);
}
嵌套subscribe()
来电始终是一个警告信号。
我猜getBookDetails
或getRoom
是异步函数,因此当代码到达return Observable.forkjoin(rooms)
时,rooms
数组始终为空。
因此,我建议您重新构建代码。例如像这样(我没有测试它,但你应该明白这一点。)
public createRooms(bookID: string): Observable<any> {
return this.modelService.getBookDetails(bookID)
.concatAll()
.concatMap(book => this.getRoom(book.name))
.concatMap(room => {
if (Object.keys(r).length === 0) {
return Observable...
} else ....
});
}
答案 1 :(得分:0)
可能是因为您需要在函数内部调用它而未调用该服务。例如,您的组件implements OnInit
因此您可以将您的服务调用放在该函数中,并使组件最终如下:
@Component({
selector: 'chat',
templateUrl: './chat.component.html'
})
export class ChatComponent implements OnInit {
public rooms = [];
public ngOnInit() {
this.selectbookStream.subscribe(bookId => {
this.chatService.getRooms(book id)
.subscribe(rooms => {
console.log("in chat component");
console.log(rooms);
this.rooms = rooms;
});
})
}
}