Сейчас у меня есть 3 компонента: singlePost, commentsList, comment (рекурсивный);
В singlePost я получаю все корневые комментарии, передаю их в commentsList, который перебирает комментарии и подгружает comment.
В comment есть коллекция replies, которая подгружает дочерние комментарии при клике на кнопку, но возникают проблемы с добавлением новых комментариев.
При добавлении нового комментария, в singlePost по сокету прилетает последний комментарий, который при помощи provide улетает в comment.
часть компонента singlePost
const comments = ref<Collection<IComment>>(new Collection<IComment>())
const lastComment = ref<IComment>()
const commentsCount = ref<number>(0)
provide('lastComment', lastComment)
provide('commentsCount', commentsCount)
const connection = new WebSocket('ws://127.0.0.1:8080/comments');
connection.onmessage = function(r) {
const comment = mapComment(JSON.parse(r.data))
lastComment.value = comment
commentsCount.value = commentsCount.value + 1
if (comment.parentId === undefined) comments.value.add(comment)
else {
const el = comments.value.find((el: IComment) => {
return el.id === comment.parentId
})
if (el !== undefined) {
if (el.replies === undefined) el.replies = 1
else el.replies += 1
}
}
};
onMounted(async () => {
const result = await getCommentsAsync(new CommentQuery({
publicationId: article.value.id,
parentId: 0
}))
if (result === null) comments.value = new Collection<IComment>()
else {
comments.value = result
commentsCount.value = article.value.commentsCount ?? 0
}
})
Кусок компонента commet
const lastComment = inject<Ref<IComment | undefined>>('lastComment') as Ref<IComment | undefined>;
const replies = ref<Collection<IComment>>(new Collection<IComment>())
const showReplies = ref(false)
const repliesCount = ref<number>(props.comment.replies)
const hasReplies = ref<boolean>(repliesCount.value > 0)
watch(lastComment, () => {
if (lastComment.value !== undefined && lastComment.value?.parentId === props.comment.id) {
replies.value.add(lastComment.value)
repliesCount.value = repliesCount.value + 1
showReplies.value = hasReplies.value = true
}
})
const showRepliesHandler = async () => {
showReplies.value = !showReplies.value
if (!replies.value.isLoaded) {
const result = await getCommentsAsync(new CommentQuery({
parentId: props.comment.id
}))
if (result !== null) {
replies.value = result
}
}
}
const repliesButtonText = computed(() => {
return showReplies.value ?
'Свернуть' : declension(repliesCount.value, ['ответ', 'ответа', 'ответов'])
})
Это работает для комментариев на n+1 уровень вложенности, то есть отображаются комментарии, в ветке, которая в данный момент раскрыта (корневые отображаются всегда).
Но если скрыть ветку, и раскрыть ее повторно, то теряются все комментарии, которые прилетели по сокету.
Кроме того, в случае, если подгружать новые комментарии по api, произойдет задвоение данных.
Как лучше сделать?