摩纳哥编辑器中的重复建议反应下一个js

问题描述 投票:0回答:2

我正在使用 monaco-edtor 在 React 和 Nextjs 中创建公式编辑器,我有一个编辑按钮来显示和隐藏编辑器,只有当用户单击编辑按钮时编辑器才会显示/安装。

首先,安装建议是按预期进行的,但是当用户隐藏并显示编辑器时,相同的元素再次重复,如下图所示,有什么方法可以纠正这个问题

建议窗口的照片。

  1. 首次安装

  2. 二次安装

  3. 第三次安装

我的代码蓝图就像

export const MonacoEditor = () => {
const editorRef = useRef<monacoEditor.editor.IStandaloneCodeEditor | null>(
        null,
    );
    
function HandleEditorDidMount(
        editor: monacoEditor.editor.IStandaloneCodeEditor,
        monaco: typeof monacoEditor,
    ) {
        editorRef.current = editor;

        editorRef.current.onKeyDown((event: monacoEditor.IKeyboardEvent) => {
            if (event.keyCode === monaco.KeyCode.Enter) {
                event.preventDefault();
            }
        });

        // Define your custom language
        monaco.languages.register({
            id: "custom-language",
        });

        editorRef.current.updateOptions({
            lineNumbers: "off",
            lineDecorationsWidth: 1,
            tabCompletion: "off",
            selectionHighlight: false,
            renderLineHighlight: "none",
            minimap: {
                enabled: false,
            },
            overviewRulerLanes: 0,
            scrollbar: {
                horizontal: "hidden",
                handleMouseWheel: true,
            },
            wordWrapColumn: -1,
            wordWrap: "on",
        });
        monaco.languages.registerCompletionItemProvider("custom-language", {
            provideCompletionItems: async (_model, position) => {
                const currentWord = getCurrentWord(editorRef.current, position);

                // Make a request to your backend API to fetch suggestions based on the user's input
                const response = await fetch("http://localhost:8000/fewLabels", {
                    method: "GET",
                });

                const suggestions: Suggestion = await response.json();
                console.log("suggestions ", suggestions);
                const completionItems = Object.keys(suggestions)
                    .filter((keyword) =>
                        keyword.toLowerCase().startsWith(currentWord.toLowerCase()),
                    )
                    .map((keyword) => ({
                        label: keyword,
                        id: keyword,
                        kind: monaco.languages.CompletionItemKind.Keyword,
                        insertText: keyword,
                        range: new monaco.Range(
                            position.lineNumber,
                            position.column - currentWord.length,
                            position.lineNumber,
                            position.column,
                        ),
                    }));

                console.log("completionItems ", completionItems);

                return {
                    suggestions: completionItems,
                };
            },
        });
    }

return(
         <Editor
                height="70px"
                width={"800px"}
                defaultLanguage="custom-language"
                onMount={HandleEditorDidMount}
            />
       )

}
javascript reactjs next.js monaco-editor react-monaco-editor
2个回答
1
投票

我解决了这个问题,我添加了一个状态

completionDisposable
,并将
monaco.languages.registerCompletionItemProvider
返回的函数设置为它,并作为清理函数调用useEffect,修改后的代码如下

修改后面有评论

// Beginning of Added Segment

// Setting the disposable object

如果您理解并为您工作,请不要忘记点赞

export const MonacoEditor = () => {
    const editorRef = useRef<monacoEditor.editor.IStandaloneCodeEditor | null>(
        null,
    );

    // Beginning of Added Segment
    const [completionDisposable, setCompletionDisposable] = useState<monacoEditor.IDisposable>();

    useEffect(() => {
        return () => {
            if (
                completionDisposable?.dispose &&
                typeof completionDisposable.dispose === "function"
            ) {
                completionDisposable.dispose();
            }
        };
    }, [completionDisposable]);

    // End of added segment



    function HandleEditorDidMount(
        editor: monacoEditor.editor.IStandaloneCodeEditor,
        monaco: typeof monacoEditor,
    ) {
        editorRef.current = editor;

        editorRef.current.onKeyDown((event: monacoEditor.IKeyboardEvent) => {
            if (event.keyCode === monaco.KeyCode.Enter) {
                event.preventDefault();
            }
        });


        // Define your custom language
        monaco.languages.register({
            id: "custom-language",
        });

        editorRef.current.updateOptions({
            lineNumbers: "off",
            lineDecorationsWidth: 1,
            tabCompletion: "off",
            selectionHighlight: false,
            renderLineHighlight: "none",
            minimap: {
                enabled: false,
            },
            overviewRulerLanes: 0,
            scrollbar: {
                horizontal: "hidden",
                handleMouseWheel: true,
            },
            wordWrapColumn: -1,
            wordWrap: "on",
        });

        // Setting the disposable object
        setCompletionDisposable(
            monaco.languages.registerCompletionItemProvider("custom-language", {
                provideCompletionItems: async (_model, position) => {
                    const currentWord = getCurrentWord(editorRef.current, position);

                    // Make a request to your backend API to fetch suggestions based on the user's input
                    const response = await fetch("http://localhost:8000/fewLabels", {
                        method: "GET",
                    });

                    const suggestions: Suggestion = await response.json();
                    console.log("suggestions ", suggestions);
                    const completionItems = Object.keys(suggestions)
                        .filter((keyword) =>
                            keyword.toLowerCase().startsWith(currentWord.toLowerCase()),
                        )
                        .map((keyword) => ({
                            label: keyword,
                            id: keyword,
                            kind: monaco.languages.CompletionItemKind.Keyword,
                            insertText: keyword,
                            range: new monaco.Range(
                                position.lineNumber,
                                position.column - currentWord.length,
                                position.lineNumber,
                                position.column,
                            ),
                        }));

                    console.log("completionItems ", completionItems);

                    return {
                        suggestions: completionItems,
                    };
                },
            }),
        );
    }


    return (
        <Editor
            height="70px"
            width={"800px"}
            defaultLanguage="custom-language"
            onMount={HandleEditorDidMount}
        />
    );
};



0
投票

我刚刚稍微更改了@SREERAG R NANDAN 的答案以满足我的需求,如下所示:

const [completionDisposable, setCompletionDisposable] = useState(null)

 useEffect(() => {
        return () => {
            if (
                completionDisposable &&
                typeof completionDisposable.dispose === 'function'
            ) {
                completionDisposable.dispose()
            }
        }
    }, [completionDisposable])

const handleOnMount = (editor, monaco) => {
        setCompletionDisposable(
            monaco.languages.registerCompletionItemProvider('json', {
                provideCompletionItems: function (model, position) {
                    const suggestions = []

                    quickSuggestions.map((word) => {
                        suggestions.push({
                            label: word,
                            kind: monaco.languages.CompletionItemKind.Text,
                            insertText: word,
                        })
                    })

                    return {
                        suggestions: suggestions,
                    }
                },
            })
        )
    }

   return ( <Editor
                 ref={editorRef}
                 height="90vh"
                 width="800px"
                 language="json"
                 theme="solarized-light"
                 value={updatedJson}
                 options={options}
                 onChange={handleEditorChange}
                 onMount={handleOnMount}
                 />)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.2.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.2.0/umd/react-dom.production.min.js"></script>

对我来说效果很好

© www.soinside.com 2019 - 2024. All rights reserved.