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 메서드에 전달된 익명 함수를 살펴보겠습니다.

이 함수는 세 가지 주요 작업을 수행합니다.
  • 편집기에서 원본 내용을 모두 삭제합니다
  • .
  • 들어오는 델타 데이터를 적용하고 편집기에 렌더링합니다
  • .
  • 1과 2를 결합한 후 델타 데이터를 반환합니다
  • .

    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 데이터를 반복하여 콘텐츠 삽입 및 콘텐츠 삭제 논리를 분리하는 것입니다. 콘텐츠 삽입 반복은 주로 두 가지 작업을 수행합니다.
  • 일반 텍스트 또는 서식 있는 텍스트 콘텐츠를 삽입하려면: insertAt
  • 텍스트 서식 지정: formatAt

  • 이 시점에서 델타 데이터를 편집기에 적용하고 렌더링하는 논리를 구문 분석했습니다.

    요약



    요약은 다음과 같습니다.
  • setContents 메서드 자체에는 로직이 없으며 수정 메서드만 호출합니다
  • .
  • Editor 개체의 applyDelta 메서드가 modify 메서드에 전달된 익명 함수에서 호출됩니다
  • .
  • applyDelta 메소드는 수신 델타 데이터를 반복하고 델타 데이터에 설명된 편집기 내용을 삽입/포맷/삭제합니다
  • .

    DevUI 팀 정보



    DevUI는 설계 및 엔지니어링 관점을 모두 갖춘 팀으로, Huawei Cloud의 DevCloud 플랫폼과 Huawei의 여러 내부 중간 및 백그라운드 시스템을 담당하고 디자이너와 프런트 엔드 엔지니어를 지원합니다.

    공식 홈페이지: devui.design

    Ng 컴포넌트 라이브러리: ng-devui (Welcome to star🌟)

    의해 Kagol

    좋은 웹페이지 즐겨찾기