构建一个即时消息应用(九):Conversation 页面 | Linux 中国
https://linux.cn/article-12723-1.html
作者:Nicolás Parada
译者:XianLei Gao
本文是该系列的第九篇,也是最后一篇。
在这篇文章中,我们将对对话页面进行编码。此页面是两个用户之间的聊天室。在顶部我们将显示其他参与者的信息,下面接着的是最新消息列表,以及底部的消息表单。
聊天标题
让我们从创建
static/pages/conversation-page.js
文件开始,它包含以下内容: http
from'../http.js'import{ navigate
}from'../router.js'import{ avatar
, escapeHTML
}from'../shared.js'exportdefaultasyncfunctionconversationPage(conversationID){let conversation
try{ conversation
=awaitgetConversation(conversationID
)}catch(err
){alert(err
.message
)navigate('/',true)return}const template
= document
.createElement('template') template
.innerHTML
=`
<div>
<a href="/">← Back</a>
${avatar(conversation.otherParticipant)}
<span>${conversation.otherParticipant.username}
</span>
</div>
<!-- message list here -->
<!-- message form here -->
`
const page
= template
.content
return page
}functiongetConversation(id){return http
.get('/api/conversations/'+ id
)}此页面接收路由从 URL 中提取的会话 ID。
首先,它向
/api/ conversations/{conversationID}
发起一个 GET 请求,以获取有关对话的信息。如果出现错误,我们会将其显示,并重定向回 /
。然后我们呈现有关其他参与者的信息。对话列表
我们也会获取最新的消息并显示它们。
conversation
, messages
try{[conversation
, messages
]=await Promise
.all([getConversation(conversationID
),getMessages(conversationID
),])}更新
conversationPage()
函数以获取消息。我们使用 Promise.all()
同时执行这两个请求。 http
.get(`/api/conversations/${conversationID}/messages`)}发起对
/api/conversations/{conversationID}/messages
的 GET 请求可以获取对话中的最新消息。现在,将该列表添加到标记中。
messagesOList
= page
.getElementById('messages')for(const message
of messages
.reverse()){ messagesOList
.appendChild(renderMessage(message
))}这样我们就可以将消息附加到列表中了。我们以时间倒序来显示它们。
messageContent
=escapeHTML(message
.content
)const messageDate
=newDate(message
.createdAt
).toLocaleString()const li
= document
.createElement('li')if(message
.mine
){ li
.classList
.add('owned')} li
.innerHTML
=`
<p>
${messageContent}</p>
<time>
${messageDate}</time>
`
return li
}每个消息条目显示消息内容本身及其时间戳。使用
.mine
,我们可以将不同的 css 类附加到条目,这样您就可以将消息显示在右侧。消息表单
Send
</button></form>将该表单添加到当前标记中。
page
.getElementById('message-form').onsubmit
=messageSubmitter(conversationID
)将事件监听器附加到 “submit” 事件。
ev
.preventDefault()const form
= ev
.currentTarget
const input
= form
.querySelector('input')const submitButton
= form
.querySelector('button') input
.disabled
=true submitButton
.disabled
=truetry{const message
=awaitcreateMessage(input
.value
, conversationID
) input
.value
=''const messagesOList
= document
.getElementById('messages')if(messagesOList
===null){return} messagesOList
.appendChild(renderMessage(message
))}catch(err
){if(err
.statusCode
===422){ input
.setCustomValidity(err
.body
.errors
.content
)}else{alert(err
.message
)}}finally{ input
.disabled
=false submitButton
.disabled
=falsesetTimeout(()=>{ input
.focus()},0)}}}functioncreateMessage(content, conversationID){return http
.post(`/api/conversations/${conversationID}/messages`,{ content
})}我们利用 partial application 在 “submit” 事件处理程序中获取对话 ID。它 从输入中获取消息内容,并用它对
/api/conversations/{conversationID}/messages
发出 POST 请求。然后将新创建的消息添加到列表中。消息订阅
为了实现实时,我们还将订阅此页面中的消息流。
page
.addEventListener('disconnect',subscribeToMessages(messageArriver(conversationID
)))将该行添加到
conversationPage()
函数中。 http
.subscribe('/api/messages', cb
)}functionmessageArriver(conversationID){returnmessage=>{if(message
.conversationID
!== conversationID
){return}const messagesOList
= document
.getElementById('messages')if(messagesOList
===null){return} messagesOList
.appendChild(renderMessage(message
))readMessages(message
.conversationID
)}}functionreadMessages(conversationID){return http
.post(`/api/conversations/${conversationID}/read_messages`)}在这里我们仍然使用这个应用的部分来获取会话 ID。当新消息到达时,我们首先检查它是否来自此对话。如果是,我们会将消息条目预先添加到列表中,并向
/api/conversations/{conversationID}/read_messages
发起 POST 一个请求,以更新参与者上次阅读消息的时间。本系列到此结束。消息应用现在可以运行了。
关键词
页面
消息
信息
中国
return http
最新评论
推荐文章
作者最新文章
你可能感兴趣的文章
Copyright Disclaimer: The copyright of contents (including texts, images, videos and audios) posted above belong to the User who shared or the third-party website which the User shared from. If you found your copyright have been infringed, please send a DMCA takedown notice to [email protected]. For more detail of the source, please click on the button "Read Original Post" below. For other communications, please send to [email protected].
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。
版权声明:以上内容为用户推荐收藏至CareerEngine平台,其内容(含文字、图片、视频、音频等)及知识版权均属用户或用户转发自的第三方网站,如涉嫌侵权,请通知[email protected]进行信息删除。如需查看信息来源,请点击“查看原文”。如需洽谈其它事宜,请联系[email protected]。