DraftJs обрезает содержимое со всеми стилями и другими свойствами, а не только с текстом

У меня есть приложение для реагирования и я использую DraftJs.

На листинговых страницах мой компонент ContentCard отображает содержимое DraftJs как доступное только для чтения с помощью Editor из draft-js.

 <Editor readOnly={true} editorState={contentState} /> 

Я хочу показать краткую версию contentState в виде краткого описания, максимум 400 символов на страницах списка. А на страницах сведений о содержимом — full contentState.

Я использовал этот метод усечения, но он обрезает только текст. Здесь я получаю блок, а затем тексты. Но как я могу получить блоки с ограничением по количеству символов.

Например; Первый блок содержит 820 символов со всеми разными словами стиля. Как я могу получить первые 400 символов со всей информацией о стилях. Я имею в виду блок из 400 символов.

truncate = (editorState, charCount) => {

    const contentState = editorState.getCurrentContent();
    const blocks = contentState.getBlocksAsArray();

    let index = 0;
    let currentLength = 0;
    let isTruncated = false;
    const truncatedBlocks = [];

    while (!isTruncated && blocks[index]) {
        const block = blocks[index];
        const length = block.getLength();
        if (currentLength + length > charCount) {
            isTruncated = true;
            const truncatedText = block
                .getText()
                .slice(0, charCount - currentLength);
            const state = ContentState.createFromText(`${truncatedText}...`);
            truncatedBlocks.push(state.getFirstBlock());
        } else {
            truncatedBlocks.push(block);
        }
        currentLength += length + 1;
        index++;
    }

    if (isTruncated) {
        const state = ContentState.createFromBlockArray(truncatedBlocks);
        return EditorState.createWithContent(state);
    }

    return editorState;
};

Я хочу показать 400 символов жирным шрифтом, курсивом, ссылками и другими объектами и так далее.


person Erdal SATIK    schedule 14.04.2019    source источник
comment
Вы хотите ограничить свой редактор до 400 символов?   -  person Sagar Pednekar    schedule 21.10.2019
comment
Не редактор. Из редактора пользователь может писать без ограничений. Например, пользователь создал статью длиной 3800 символов. Но когда я перечисляю этот контент и отображаю элемент контента с помощью объекта JSON содержимого Draft JS на домашней странице, элементы списка должны иметь длину 400 символов.   -  person Erdal SATIK    schedule 22.10.2019


Ответы (1)


Мне нужно было что-то подобное, поэтому я сделал очень грубую реализацию, но у меня это сработало :)

import { ContentState, convertToRaw } from 'draft-js'

const convertContentToEditorState = (content: string) => {
    if (content) {
        try {
            return EditorState.createWithContent(
                convertFromRaw(JSON.parse(content)),
            )
        } catch {
            return EditorState.createEmpty()
        }
    } else {
        return EditorState.createEmpty()
    }
}

/**
 * Takes in a stringfied JSON object, truncates it into a single ContentState and returns it.
 * @param jsonContentBlocks
 * @param maxCharCount
 */
const getTruncatedContentState = (
    jsonContentBlocks: string,
    maxCharCount: number,
): ContentState | undefined => {
    const editorState = convertContentToEditorState(jsonContentBlocks)

    const contentState = editorState.getCurrentContent()
    const blocks = contentState.getBlocksAsArray()

    let currentLength = 0
    const truncatedBlocks = []

    for (let i = 0; i < blocks.length; i++) {
        const blockLength = blocks[i].getCharacterList().size
        let truncatedText = ''

        if (blockLength >= maxCharCount - currentLength) {
            // We need to trim it
            truncatedText = blocks[i]
                .getText()
                .slice(0, maxCharCount - currentLength)
            currentLength += truncatedText.length

            const state = ContentState.createFromText(`${truncatedText}...`)
            truncatedBlocks.push(state.getFirstBlock())
            break
        } else if (blockLength > 0) {
            truncatedText = blocks[i].getText()
            currentLength += truncatedText.length

            const state = ContentState.createFromText(`${truncatedText}`)
            truncatedBlocks.push(state.getFirstBlock())
        }
    }

    if (truncatedBlocks.length > 0) {
        return ContentState.createFromBlockArray(truncatedBlocks)
    }

    return undefined
}

/**
 * Truncates and gets only the text from the blocks, returns stringified JSON
 * @param jsonContentBlocks
 * @param maxCharCount
 */
const getTruncatedContent = (
    jsonContentBlocks: string | undefined,
    maxCharCount: number,
): string | undefined => {
    if (!jsonContentBlocks) return undefined

    const contentState = getTruncatedContentState(
        jsonContentBlocks,
        maxCharCount,
    )

    if (contentState) {
        const raw = convertToRaw(contentState)
        return JSON.stringify(raw)
    }

    return undefined
}
person haukurmar    schedule 27.07.2020