CKEditor5-接收“模型节点列表偏移量超出范围”。发生此错误的可能原因是什么?

时间:2018-06-20 15:17:44

标签: javascript ckeditor ckeditor5

尝试在CKEditor5中创建自定义插件后,出现以下错误(“ model-nodelist-offset-out-of-bounds”)。该插件采用三个用户输入值,并创建带有三个文本节点的一系列嵌套元素。我的自定义向下转换功能包含...

    const testimonial = data.item;

    // Retrieves attributes from custom 'testimonial' element
    let body = testimonial.getAttribute( 'testimonialBody' );
    let author = testimonial.getAttribute( 'testimonialAuthor' );
    let about = testimonial.getAttribute( 'testimonialAbout' );

    // Element creation
    const testWrapperElement = conversionApi.writer.createContainerElement( 'div', { class: 'callout__interbodyquote' } );
    const testBodyElement = conversionApi.writer.createContainerElement( 'p', { class: 'body_testimonial' } );
    const testSubBodyElement = conversionApi.writer.createContainerElement( 'div' );
    const testIconElement = conversionApi.writer.createContainerElement( 'image', { class: 'icon__testimonial', src: testimonialIcon } );
    const testFooterWrapperElement = conversionApi.writer.createContainerElement( 'div' );
    const testAuthorElement = conversionApi.writer.createContainerElement( 'p', { class: 'author_testimonial' } );
    const testAboutElement = conversionApi.writer.createContainerElement( 'p', { class: 'about_testimonial' } );

    // Text element creation
    const bodyText = conversionApi.writer.createText( body );
    const authorText = conversionApi.writer.createText( author );
    const aboutText = conversionApi.writer.createText( about );   

    // Combining/nesting elements
    let insertPosition = ViewPosition.createAt( testWrapperElement, 'end' );
    conversionApi.writer.insert( insertPosition, testBodyElement );
    insertPosition = ViewPosition.createAt( testWrapperElement, 'end' );
    conversionApi.writer.insert( insertPosition, testSubBodyElement );
    insertPosition = ViewPosition.createAt( testBodyElement, 'end' );
    conversionApi.writer.insert( insertPosition, bodyText );
    insertPosition = ViewPosition.createAt( testSubBodyElement, 'end' );
    conversionApi.writer.insert( insertPosition, testFooterWrapperElement );
    insertPosition = ViewPosition.createAt( testSubBodyElement, 'end' );
    conversionApi.writer.insert( insertPosition, testIconElement );
    insertPosition = ViewPosition.createAt( testFooterWrapperElement, 'end' );
    conversionApi.writer.insert( insertPosition, testAuthorElement );
    insertPosition = ViewPosition.createAt( testFooterWrapperElement, 'end' );
    conversionApi.writer.insert( insertPosition, testAboutElement );
    insertPosition = ViewPosition.createAt( testAboutElement, 'end' );
    conversionApi.writer.insert( insertPosition, aboutText );
    insertPosition = ViewPosition.createAt( testAuthorElement, 'end' );
    conversionApi.writer.insert( insertPosition, authorText );

    const viewPosition = conversionApi.mapper.toViewPosition( data.range.start );
    conversionApi.mapper.bindElements( testimonial, testWrapperElement );
    conversionApi.writer.insert( viewPosition, testWrapperElement );

我的命令如下...

    export default class TestimonialCommand extends Command {
        refresh() {
            const model = this.editor.model;
            const selection = model.document.selection;
            const schema = model.schema;

            const validParent = getInsertTestimonialParent( selection.getFirstPosition() );

            // Check if custom testimonial element is allowed within the current parent (based on cursor location)
            this.isEnabled = schema.checkChild( validParent, 'testimonial' );
        }

        execute(body, author, about) {
            const model = this.editor.model;
            const selection = model.document.selection;

            model.change(writer => {
                const firstPosition = selection.getFirstPosition();
                const isRoot = firstPosition.parent === firstPosition.root;
                const insertPosition = isRoot ? Position.createAt( firstPosition ) : Position.createAfter( firstPosition.parent );

                // Creates custom testimonial element with user input as custom attributes.
                // These attributes will be pulled off the element during the downcasting and converted into 
                // text within a testimonial block of HTML. 
                const testimonial = writer.createElement( 'testimonial', { 'testimonialBody': body, 'testimonialAuthor': author, 'testimonialAbout': about } );

                writer.insert( testimonial, insertPosition );
            })
        }
    }

    // Retrieves parent element 
    function getInsertTestimonialParent( position ) {
        const parent = position.parent;

        return parent === parent.root ? parent : parent.parent;
    }

我完全收到的错误显示为...

Uncaught CKEditorError: model-nodelist-offset-out-of-bounds: Given offset cannot be found in the node list.

诸如此类的错误的可能原因是什么?

预先感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

我在开发自己的小部件时遇到了相同的错误,并使用viewToModelPositionOutsideModelElement实用程序解决了该错误。

  

抛出此错误是因为文本节点存在差异   由于结构不同,模型与视图之间的映射

您可以在CKEditor文档中直接阅读以下内容:Fixing position mapping