4

我编写了一个表格模块,其中包括一个过滤器模块、一个标签导航模块和一个分页模块。该表格模块由不同的父组件实现,例如用户列表或消息列表。父级将对象列表发送到表格模块,然后将其发送到不同的子组件(过滤器、选项卡导航、分页)。是仅将分页作为一个子组件的基本设置。

为了将消息列表作为对话列表,我构建了一个对话服务,其中所有消息都从服务器接收并转换为对话列表。当服务中的对话列表发生变化时,会触发一个事件。因为消息列表组件订阅了这个事件,所以消息列表中的列表也会改变。

@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;
    }
}
4

0 回答 0