我编写了一个表格模块,其中包括一个过滤器模块、一个标签导航模块和一个分页模块。该表格模块由不同的父组件实现,例如用户列表或消息列表。父级将对象列表发送到表格模块,然后将其发送到不同的子组件(过滤器、选项卡导航、分页)。这是仅将分页作为一个子组件的基本设置。
为了将消息列表作为对话列表,我构建了一个对话服务,其中所有消息都从服务器接收并转换为对话列表。当服务中的对话列表发生变化时,会触发一个事件。因为消息列表组件订阅了这个事件,所以消息列表中的列表也会改变。
@Injectable()
export class ConversationService {
private conversationList: Conversation[];
private changeConversationListSource = new Subject<any[]>();
conversationListChanged$ = this.changeConversationListSource.asObservable();
constructor(
private authService: AuthenticationService,
private messageService: MessageService) { }
getConversationList() {
if (this.conversationList)
this.changeConversationListSource.next(this.conversationList);
else
this.getMessages()
.then(messages => {
this.buildConversations(messages); // conversationList built in here
this.changeConversationListSource.next(this.conversationList);
});
}
private getMessages(): Promise<Message[]> {
return this.messageService
.getMessagesByUserId(this.authService.getAuthElement().userId);
}
}
问题是当我第一次访问页面时,在分页中转换列表后显示的表格不会改变。当我再次访问该页面时,单击选项卡导航的选项卡或分页的站点按钮即可。这只发生在消息列表组件而不是用户列表组件上。奇怪的是,只有表格本身不会正确显示,表格模块中接收到的对象列表通过分页正确转换。
如您所见,BehaviorSubject 包含 3 个对象,但该表有 6 个条目。如上所述单击任何按钮后,视图会正确更改。
当我不在 ConversationService 中进行 API 调用时,它可以工作。
getConversationList() {
this.changeConversationListSource.next([
new Conversation(),
new Conversation(),
new Conversation(),
new Conversation(),
new Conversation(),
new Conversation()
]);
}
那么什么可能导致这个问题呢?
更新 1
这是构建对话列表的代码。
private buildConversations(messages: Message[]): void {
let conversations: Conversation[] = []; //
let users = this.groupUsers(messages); //
conversations = conversations.concat( //
this.buildConversationList(users.internUsers, messages));
conversations = conversations.concat( //
this.buildConversationList(users.externUsers, messages));
this.conversationList = conversations;
}
private buildConversationList(users: any[], messages: Message[]): Conversation[] {
let conversations: Conversation[] = [];
let conversation: Conversation;
users.forEach(user => {
for (let category in MessageCategory) {
conversation = new Conversation();
conversation.category = MessageCategory[category];
if (typeof user === 'string') conversation.externPartner = user;
else conversation.internPartner = user;
conversation.messages = messages.filter(message => {
if (message.category === MessageCategory[category])
if (typeof user === 'string')
return this.checkExternMessage(message, user, conversation);
else
return this.checkInternMessage(message, user, conversation);
});
if (conversation.messages.length > 0) conversations.push(conversation);
}
});
return conversations;
}
private checkExternMessage(message: Message, user: string, conversation: Conversation): boolean {
if (message.receiver === undefined && message.sender === undefined)
if (message.receiverMail !== null && message.receiverMail === user) {
if (!message.isRead && this.messageService.isUserMessageReceiver(message))
conversation.newMessages++;
return true;
}
else if (message.senderMail !== null && message.senderMail === user) {
if (!message.isRead && this.messageService.isUserMessageReceiver(message))
conversation.newMessages++;
return true;
}
return false;
}
private checkInternMessage(message: Message, user: User, conversation: Conversation): boolean {
if (message.receiver !== undefined && message.sender !== undefined)
if (message.receiver !== null && message.receiver.id === user.id) {
if (!message.isRead && this.messageService.isUserMessageReceiver(message))
conversation.newMessages++;
return true;
}
else if (message.sender !== null && message.sender.id === user.id) {
if (!message.isRead && this.messageService.isUserMessageReceiver(message))
conversation.newMessages++;
return true;
}
return false;
}
更新 2
在发现里面的错误时,this.buildConversations()
我认识到错误不能在这个函数中。当我执行以下操作时,我会遇到与以前相同的错误。
private buildConversations(messages: Message[]): void {
let conversations: Conversation[] = [];
let users = this.groupUsers(messages);
for (var i = 0; i < 10; i++)
conversations.push(new Conversation());
this.conversationList = conversations;
}
因此,在 API 调用期间肯定会出现错误,但我找不到任何错误。这是 API 调用的代码。
@Injectable()
export class MessageService {
private newMessages: number;
newMessagesChanged: EventEmitter<number>;
constructor(
private authService: AuthenticationService,
private httpClient: HttpClient) {
this.newMessagesChanged = new EventEmitter<number>();
}
getMessagesByUserId(userId: number): Promise<Message[]> {
if (this.messages)
return new Promise<Message[]>((resolve, reject) => resolve(this.messages));
return this.httpClient
.get(MessageService.API + userId, this.httpClient.getHeader())
.then(res => this.handleMessageList(this.httpClient.extractData(res)));
}
private handleMessageList(messages: Message[]): Message[] {
this.newMessages = 0;
this.messages = messages;
this.messages.forEach(message => {
if (!message.isRead && this.isUserMessageReceiver(message))
this.newMessages++;
});
this.newMessagesChanged.emit(this.newMessages);
return this.messages;
}
}