提问人:Lee 提问时间:9/30/2023 最后编辑:Lee 更新时间:10/1/2023 访问量:168
来自数据库的数据不会保留在 tiptap 编辑器内容中
Data from database does not persist in tiptap editor content
问:
更新
从我收到的关于这个问题的一些建议中,我现在发现,无论是将我的 recipe.ingredients 设置为本地存储,还是将 setContent 与 useEffect 一起使用,如下所示,确实在 tiptap 编辑器中设置了一个持久值。但是,使用这两种方法中的任何一种都会导致不同的问题,即在我刷新页面之前,内容不会呈现。这意味着编辑器是空的,除非页面由于某种延迟而刷新。就像下面描述的问题一样,如果我输入一个html值,我就没有这个问题。例如,如果我控制台.log(recipe.ingredients),然后将控制台中的html剪切并粘贴到编辑器上的内容中,则一切正常,但是如果我尝试传递recipe.ingredients,则在我刷新页面之前它不会呈现。由于当我输入用引号括起来的 html 字符串时它起作用,因此我尝试将值括在引号中,然后像这样传递它:
`'`+ recipe.ingredients + `'`
这只会导致我最初的问题中描述的相同问题,但显示了引号。
总而言之,这在页面刷新之前不起作用:
const editor = useEditor({
extensions,
content:'',
onUpdate: ({ editor }) => {
const html = editor.getHTML();
setIngredients(html);
editor.commands.clearContent()
console.log(html);
},
})
useEffect(() => {
if (!editor) {
return undefined
}
editor.commands.setContent(recipe.ingredients)
}, [editor])
if (!editor) {
return null
}
但是像这样写出的 Recipe.Ingredients 的 HTML 值工作正常:
const editor = useEditor({
extensions,
content:'',
onUpdate: ({ editor }) => {
const html = editor.getHTML();
setIngredients(html);
console.log(html);
},
})
useEffect(() => {
if (!editor) {
return undefined
}
editor.commands.setContent('<ul><li><p>mac</p></li><li>
<p>cheese</p></li></ul>')
}, [editor])
if (!editor) {
return null
}
结束更新原题:
当我将数据从数据库中的字段传递到 TipTap 编辑器的内容时,我在刷新时丢失了 TipTap 编辑器(基于 ProseMirror)的内容。
我的目标是从数据库中的 recipe 对象中获取 ingredients 字段,并将其传递给 tiptap 编辑器。数据采用 html 格式,是在我的“添加食谱”表单中使用 TipTap 编辑器创建的。我希望数据在这个新的TipTap编辑器中显示并可编辑,这将是用户“编辑食谱”表单的一部分。请注意,我相信这与这里提出的问题相同:如何持久化数据,使其不会在 TipTap 编辑器中被删除?但是,该问题没有提供任何示例代码,因此我在问题中提供了更多上下文。
这是我当前的代码,我将 recipe.ingredients 数据传递给 TipTap 编辑器内容:
// define your extension array
const extensions = [
Color.configure({ types: [TextStyle.name, ListItem.name] }),
TextStyle.configure({ types: [ListItem.name] }),
StarterKit.configure({
bulletList: {
keepMarks: true,
keepAttributes: false, // TODO : Making this as `false` becase marks are not preserved when I try to preserve attrs, awaiting a bit of help
},
orderedList: {
keepMarks: true,
keepAttributes: false, // TODO : Making this as `false` becase marks are not preserved when I try to preserve attrs, awaiting a bit of help
}
}),
// Placeholder.configure({
// placeholder: 'Ingredients',
// }),
Underline,
TextAlign.configure({
types: ['heading', 'paragraph'],
alignments: ['left', 'right'],
defaultAlignment: 'left',
})
]
const TiptapIngredientsEdit = ({setIngredients}) => {
const { id }= useParams();
const initialRecipeState = {
id: null,
title: "",
description: "",
recipeType: "",
servingSize: null,
ingredients: "",
directions: "",
source: "",
userId: undefined
};
const [recipe, setRecipe] = useState(initialRecipeState);
//get recipe
const getRecipe = id => {
RecipeDataService.get(id)
.then(response => {
setRecipe(response.data);
console.log(response.data.ingredients);
})
.catch(e => {
console.log(e);
});
};
useEffect(() => {
if(id)
getRecipe(id);
}, [id]);
const editor = useEditor({
extensions,
content: recipe.ingredients,
onUpdate: ({ editor }) => {
const html = editor.getHTML();
setIngredients(html);
console.log(html);
}
})
return (
<>
<Box sx={{ mb: "4px", border: 1, borderColor: 'rgb(196, 196, 196)', borderRadius: '5px'}}>
<MenuBar editor={editor} />
<EditorContent editor={editor} />
</Box>
</>
)
}
export default TiptapIngredientsEdit
成分最初按预期从 html 呈现,并可以根据需要进行编辑:
但是在页面刷新后,编辑器内容变为空白:
如果我提供一个像这样的内容的html字符串,我不会遇到同样的问题,所以将数据从数据库传递到内容似乎是一个问题:
const editor = useEditor({
extensions,
content: '<b>test content</b>',
onUpdate: ({ editor }) => {
const html = editor.getHTML();
setIngredients(html);
console.log(html);
}
})
答:
您需要在初始化时进行编辑,并且您的内容为空,我们需要直接将内容设置为编辑器对象。ingredients
ingredients
useEditor
因此,根据解决方案,只需将成分设置为使用命令即可。您可以在此处查看详细信息。https://tiptap.dev/api/commands/set-contenteditor
setContent
代码需要添加
useEffect(() => {
editor.commands.setContent(recipe.ingredients)
}, [recipe]);
您更新的代码
// define your extension array
const extensions = [
Color.configure({ types: [TextStyle.name, ListItem.name] }),
TextStyle.configure({ types: [ListItem.name] }),
StarterKit.configure({
bulletList: {
keepMarks: true,
keepAttributes: false, // TODO : Making this as `false` becase marks are not preserved when I try to preserve attrs, awaiting a bit of help
},
orderedList: {
keepMarks: true,
keepAttributes: false, // TODO : Making this as `false` becase marks are not preserved when I try to preserve attrs, awaiting a bit of help
}
}),
// Placeholder.configure({
// placeholder: 'Ingredients',
// }),
Underline,
TextAlign.configure({
types: ['heading', 'paragraph'],
alignments: ['left', 'right'],
defaultAlignment: 'left',
})
]
const TiptapIngredientsEdit = ({setIngredients}) => {
const { id }= useParams();
const initialRecipeState = {
id: null,
title: "",
description: "",
recipeType: "",
servingSize: null,
ingredients: "",
directions: "",
source: "",
userId: undefined
};
const [recipe, setRecipe] = useState(initialRecipeState);
//get recipe
const getRecipe = id => {
RecipeDataService.get(id)
.then(response => {
setRecipe(response.data);
console.log(response.data.ingredients);
})
.catch(e => {
console.log(e);
});
};
useEffect(() => {
if(id)
getRecipe(id);
}, [id]);
useEffect(() => {
editor.commands.setContent(recipe.ingredients)
}, [recipe]);
const editor = useEditor({
extensions,
content: recipe.ingredients,
onUpdate: ({ editor }) => {
const html = editor.getHTML();
setIngredients(html);
console.log(html);
}
})
return (
<>
<Box sx={{ mb: "4px", border: 1, borderColor: 'rgb(196, 196, 196)', borderRadius: '5px'}}>
<MenuBar editor={editor} />
<EditorContent editor={editor} />
</Box>
</>
)
}
export default TiptapIngredientsEdit
谢谢
评论
这是最终版本,根据 I_am_prince 的答案,我可以解决所有这些问题,但进行了一些更改以使其在我的代码中正常工作:
const editor = useEditor({
extensions,
content: '',
onUpdate: ({ editor }) => {
const html = editor.getHTML();
setIngredients(html);
console.log(html);
},
contentEditable: "true"
})
useEffect(() => {
if (editor && !editor.isDestroyed) editor.commands.setContent(recipe.ingredients);
}, [recipe.ingredients]);
return (
<>
<Box sx={{ mb: "4px", border: 1, borderColor: 'rgb(196, 196, 196)', borderRadius: '5px'}}>
<MenuBar editor={editor} />
<EditorContent editor={editor} />
</Box>
</>
)
}
评论