我想让 solid mason 库能够处理具有未定义初始高度的元素(事实并非如此)。
导致问题的组件如下所示,大小不确定,因为我们不知道传入的文本量。这会导致库计算错误,最终导致元素重叠。
export const NoteItem = (props: { noteInfo: NoteRef }) => {
const [loading, setLoading] = createSignal(true);
const [noteContent, setNoteContent] = createSignal('');
const content = async () => {
const note = await get_note_content(props.noteInfo.notepath);
setNoteContent(note);
setLoading(false);
};
onMount(() => {
content();
});
return (
<Show when={!loading()}>
<Dialog>
<DialogTrigger class="w-full">
<div class="max-h-[500px] min-h-[50px] w-full overflow-hidden rounded-xl border border-transparent bg-foreground/10 p-6 shadow-md hover:border-secondary">
<NoteContent content={noteContent()} />
</div>
{props.noteInfo.metadata.name === '' ? null : (
<p class="mt-[10px] h-5 overflow-hidden text-ellipsis whitespace-nowrap text-center text-sm font-medium text-muted/80">
{props.noteInfo.metadata.name}
</p>
)}
</DialogTrigger>
<ViewBox source={props.noteInfo} content={noteContent()} type="note" />
</Dialog>
</Show>
);
};
const NoteContent = (props: { content: string }) => {
const [container, setContainer] = createSignal<HTMLDivElement>();
// createEffect(() => {
// window.dispatchEvent(new Event('resize'));
// });
createTiptapEditor(() => ({
element: container()!,
editable: false,
extensions: [
StarterKit,
Markdown.configure({
transformPastedText: true,
transformCopiedText: true,
}),
],
editorProps: {
attributes: {
class:
'focus:outline-none prose dark:prose-invert prose-sm sm:prose-base lg:prose-lg xl:prose-xl max-w-full h-full ',
},
},
content: props.content,
}));
return <div ref={setContainer} class="h-full overflow-y-scroll text-start" />;
};
当我调整窗口大小时,库的 manson 组件会重新计算整个网格,并且元素会转到正确的位置,因此我尝试从我的笔记组件发送调整大小 js 事件,但它没有解决问题。
createEffect(() => {
window.dispatchEvent(new Event('resize'));
});
您的实施存在几个问题。结果就是这些问题的结果。
Solid-Mason 已经监听并处理调整大小事件,因此您不必手动触发它。您不应触发调整大小事件,但如有必要,应使用它与底层元素进行交互。为此,您可以使用 ref 或
onMount
钩子。但是,对于这个用例来说,甚至没有必要,因为您的目的是先获取数据,然后渲染它。
您将组件状态拆分为三个信号,这很难管理,并且会使您的组件多次重新渲染。由于您使用的是异步值,因此最好创建一个资源并使用其状态和数据:https://www.solidjs.com/docs/latest/api#createresource
您正在组件渲染后影响内容。您应该先获取内容然后再渲染它。所以这个逻辑不仅是错误的,而且即使在数据可用后也会触发多次不必要的重新渲染:
const content = async () => {
const note = await get_note_content(props.noteInfo.notepath);
setNoteContent(note);
setLoading(false);
};
onMount(() => {
content();
});
使用资源也可以解决这个问题。只需在主组件中获取数据并在资源解析为值后渲染内容即可。
具有不同数量的文本应该不是问题,因为solid-mason 不要求您提供相同高度的元素。您可以稍微清理一下 CSS 以提供固定的元素。
如果您使用 stackblitz 或 Codesandbox 等在线游乐场之一创建现场演示,人们可以提供更具体的解决方案。