Quill은 델타를 DOM으로 어떻게 변환합니까? 3월 10일
도입
에서 우리는 Quill이 델타를 사용하여 편집기 콘텐츠와 변형을 설명하는 방법을 보여주었습니다. 우리는 Delta가 3개의 작업과 1개의 속성만 있는 일반적인 JSON 구조일 뿐이라는 것을 배웠지만 매우 표현력이 뛰어납니다.
그렇다면 Quill은 델타 데이터를 어떻게 적용하고 편집기에 렌더링합니까?
setContents 사용 방법
Quill에는 델타 데이터를 편집기로 렌더링하는 setContents라는 API가 있습니다. 이 게시물은 이 API가 구현되는 방법에 중점을 둘 것입니다.
이전 게시물의 델타 데이터를 예로 들어 보겠습니다.
const delta = { "ops": [
{ "insert": "Hello " },
{ "insert": "World", "attributes": { "bold": true } },
{ "insert": "\n" } ]
}
new Quill()을 사용하여 Quill의 인스턴스를 생성하면 해당 API를 호출할 수 있습니다.
const quill = new Quill('#editor', {
theme: 'snow'
});
setContents 메서드를 호출하여 방금 보유한 델타 데이터를 전달해 보겠습니다.
quill.setContents(delta);
예상되는 형식화된 텍스트가 편집기에 나타납니다.
setContents에 대해 자세히 알아보기
setContents의 소스를 살펴봄으로써 modify 메소드를 호출하고 함수를 전달합니다.
setContents(delta, source = Emitter.sources.API) {
return modify.call( this, () => {
delta = new Delta(delta);
const length = this.getLength();
const deleted = this.editor.deleteText(0, length);
const applied = this.editor.applyDelta(delta);
... // The non-core code is omitted for ease of reading
return deleted.compose(applied);
}, source, );
}
call 메서드는 현재 Quill 인스턴스를 참조하는 내부 this 포인터를 변경하기 위해 modify를 호출하는 데 사용됩니다. 수정 방법은 Quill 클래스에 정의되어 있지 않으므로 수행해야 합니다.
modify 메서드 대신 modify 메서드에 전달된 익명 함수를 살펴보겠습니다.
이 함수는 세 가지 주요 작업을 수행합니다.
Quill에는 델타 데이터를 편집기로 렌더링하는 setContents라는 API가 있습니다. 이 게시물은 이 API가 구현되는 방법에 중점을 둘 것입니다.
이전 게시물의 델타 데이터를 예로 들어 보겠습니다.
const delta = { "ops": [
{ "insert": "Hello " },
{ "insert": "World", "attributes": { "bold": true } },
{ "insert": "\n" } ]
}
new Quill()을 사용하여 Quill의 인스턴스를 생성하면 해당 API를 호출할 수 있습니다.
const quill = new Quill('#editor', {
theme: 'snow'
});
setContents 메서드를 호출하여 방금 보유한 델타 데이터를 전달해 보겠습니다.
quill.setContents(delta);
예상되는 형식화된 텍스트가 편집기에 나타납니다.
setContents에 대해 자세히 알아보기
setContents의 소스를 살펴봄으로써 modify 메소드를 호출하고 함수를 전달합니다.
setContents(delta, source = Emitter.sources.API) {
return modify.call( this, () => {
delta = new Delta(delta);
const length = this.getLength();
const deleted = this.editor.deleteText(0, length);
const applied = this.editor.applyDelta(delta);
... // The non-core code is omitted for ease of reading
return deleted.compose(applied);
}, source, );
}
call 메서드는 현재 Quill 인스턴스를 참조하는 내부 this 포인터를 변경하기 위해 modify를 호출하는 데 사용됩니다. 수정 방법은 Quill 클래스에 정의되어 있지 않으므로 수행해야 합니다.
modify 메서드 대신 modify 메서드에 전달된 익명 함수를 살펴보겠습니다.
이 함수는 세 가지 주요 작업을 수행합니다.
setContents(delta, source = Emitter.sources.API) {
return modify.call( this, () => {
delta = new Delta(delta);
const length = this.getLength();
const deleted = this.editor.deleteText(0, length);
const applied = this.editor.applyDelta(delta);
... // The non-core code is omitted for ease of reading
return deleted.compose(applied);
}, source, );
}
Editor 클래스의 applyDelta 메서드와 관련된 2단계에 초점을 맞추겠습니다.
applyDelta 방법 작동 방식
이름에서 짐작할 수 있듯이 이 방법의 목적은 들어오는 Delta 데이터를 편집기에 적용하고 렌더링하는 것입니다.
우리가 짐작할 수 있듯이 구현은 루프 Delta의 ops 배열이 편집기에 하나씩 적용된다는 것입니다.
소스 코드는 54줄 길이이며 다음과 같습니다.
applyDelta(delta) {
let consumeNextNewline = false;
this.scroll.update();
let scrollLength = this.scroll.length();
this.scroll.batchStart();
const normalizedDelta = normalizeDelta(delta);
normalizedDelta.reduce((index, op) => {
const length = op.retain || op.delete || op.insert.length || 1;
let attributes = op.attributes || {};
// 1.Insert text
if (op.insert != null) {
if (typeof op.insert === 'string') {
// Plain text content
let text = op.insert;
... // For ease of reading, omit non-core code
this.scroll.insertAt(index, text);
... // For ease of reading, omit non-core code
} else if (typeof op.insert === 'object') {
// Rich text content
const key = Object.keys(op.insert)[0];
// There should only be one key
if (key == null) return index;
this.scroll.insertAt(index, key, op.insert[key]);
}
scrollLength += length;
}
// 2.Formatting the text
Object.keys(attributes).forEach(name => {
this.scroll.formatAt(index, length, name, attributes[name]);
});
return index + length;
}, 0);
... // For ease of reading, omit non-core code
this.scroll.batchEnd();
this.scroll.optimize();
return this.update(normalizedDelta);
}
추측한 대로 이 방법은 Delta reduce 메서드를 사용하여 들어오는 Delta 데이터를 반복하여 콘텐츠 삽입 및 콘텐츠 삭제 논리를 분리하는 것입니다. 콘텐츠 삽입 반복은 주로 두 가지 작업을 수행합니다.
applyDelta(delta) {
let consumeNextNewline = false;
this.scroll.update();
let scrollLength = this.scroll.length();
this.scroll.batchStart();
const normalizedDelta = normalizeDelta(delta);
normalizedDelta.reduce((index, op) => {
const length = op.retain || op.delete || op.insert.length || 1;
let attributes = op.attributes || {};
// 1.Insert text
if (op.insert != null) {
if (typeof op.insert === 'string') {
// Plain text content
let text = op.insert;
... // For ease of reading, omit non-core code
this.scroll.insertAt(index, text);
... // For ease of reading, omit non-core code
} else if (typeof op.insert === 'object') {
// Rich text content
const key = Object.keys(op.insert)[0];
// There should only be one key
if (key == null) return index;
this.scroll.insertAt(index, key, op.insert[key]);
}
scrollLength += length;
}
// 2.Formatting the text
Object.keys(attributes).forEach(name => {
this.scroll.formatAt(index, length, name, attributes[name]);
});
return index + length;
}, 0);
... // For ease of reading, omit non-core code
this.scroll.batchEnd();
this.scroll.optimize();
return this.update(normalizedDelta);
}
이 시점에서 델타 데이터를 편집기에 적용하고 렌더링하는 논리를 구문 분석했습니다.
요약
요약은 다음과 같습니다.
DevUI 팀 정보
DevUI는 설계 및 엔지니어링 관점을 모두 갖춘 팀으로, Huawei Cloud의 DevCloud 플랫폼과 Huawei의 여러 내부 중간 및 백그라운드 시스템을 담당하고 디자이너와 프런트 엔드 엔지니어를 지원합니다.
공식 홈페이지: devui.design
Ng 컴포넌트 라이브러리: ng-devui (Welcome to star🌟)
의해 Kagol
Reference
이 문제에 관하여(Quill은 델타를 DOM으로 어떻게 변환합니까? 3월 10일), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/devui/how-does-quill-convert-delta-to-dom-2664
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
Reference
이 문제에 관하여(Quill은 델타를 DOM으로 어떻게 변환합니까? 3월 10일), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/devui/how-does-quill-convert-delta-to-dom-2664텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)