스키마 정의
멘션 노드 타입의 스키마 정의:
{
mention: {
inline: true,
attrs: {
id: { default: '' },
label: { default: '' }
},
}
}모델 표현
모델 표현 예제:
{
type: 'mention',
attrs: {
id: 'user123',
label: '@사용자명'
}
}HTML 직렬화
모델을 HTML로 변환:
function serializeMention(node) {
return '<span data-type="mention" data-id="' + escapeHtml(node.attrs.id) +
'">' + escapeHtml(node.attrs.label) + '</span>';
}HTML 역직렬화
HTML을 모델로 파싱:
function parseMention(domNode) {
return {
type: 'mention',
attrs: {
id: domNode.getAttribute('data-id') || '',
label: domNode.textContent || ''
}
};
}뷰 연동
뷰 연동 노트: 이 노드 타입을 뷰 레이어에서 구현할 때 contenteditable 동작, 선택 처리, 이벤트 관리에 특히 주의하세요.
뷰 연동 코드:
// 멘션 렌더링
const mention = document.createElement('span');
mention.setAttribute('data-type', 'mention');
mention.setAttribute('data-id', node.attrs.id);
mention.textContent = node.attrs.label;
mention.className = 'mention';
mention.contentEditable = 'false'; // 멘션은 일반적으로 직접 편집되지 않음일반적인 문제
일반적인 함정: 이 노드 타입을 구현할 때 자주 발생하는 문제들입니다. 구현 전에 주의 깊게 검토하세요.
일반적인 문제 및 해결 방법:
// 문제: 멘션 자동완성
// 해결: 멘션 자동완성 구현
function handleMentionInput(e) {
const query = e.target.value;
if (query.startsWith('@')) {
showMentionSuggestions(query.slice(1));
}
}
// 문제: 멘션 삭제
// 해결: 멘션을 단위로 삭제 처리
function handleMentionDeletion(mention) {
// 멘션 전체를 삭제, 일부만 삭제하지 않음
mention.remove();
}구현
완전한 구현 예제:
class MentionNode {
constructor(attrs) {
this.type = 'mention';
this.attrs = {
id: attrs?.id || '',
label: attrs?.label || ''
};
}
toDOM() {
const mention = document.createElement('span');
mention.setAttribute('data-type', 'mention');
mention.setAttribute('data-id', this.attrs.id);
mention.textContent = this.attrs.label;
mention.className = 'mention';
return mention;
}
static fromDOM(domNode) {
return new MentionNode({
id: domNode.getAttribute('data-id') || '',
label: domNode.textContent || ''
});
}
}