function EditorField({ value, onChange, env }) {
const editorRef = React.useRef(null);
const containerRef = React.useRef(null);
const [isLoading, setIsLoading] = React.useState(true);
React.useEffect(() => {
if (editorRef.current || !containerRef.current) return;
// 加载 JSONEditor 的 CSS 和 JS
const loadStyles = () => {
const link = document.createElement('link');
link.href = 'https://cdn.bootcdn.net/ajax/libs/jsoneditor/10.1.0/jsoneditor.min.css';
link.rel = 'stylesheet';
link.type = 'text/css';
document.head.appendChild(link);
return link;
};
const styleElement = loadStyles();
const script = document.createElement('script');
script.src = 'https://cdn.bootcdn.net/ajax/libs/jsoneditor/10.1.0/jsoneditor.min.js';
script.async = true;
script.onload = () => {
const options = {
mode: 'tree',
modes: ['tree', 'code', 'text'],
onChangeJSON: (json) => {
try {
onChange(JSON.stringify(json));
} catch (err) {
console.error('JSON转换失败:', err);
}
},
onModeChange: (newMode) => {
console.log('编辑器模式切换为:', newMode);
},
search: true,
statusBar: true,
mainMenuBar: true,
navigationBar: true,
readOnly: env.isDisabled
};
try {
editorRef.current = new window.JSONEditor(containerRef.current, options);
// 设置初始值
const initialValue = value ? JSON.parse(value) : {};
editorRef.current.set(initialValue);
setIsLoading(false);
} catch (err) {
console.error('JSONEditor初始化失败:', err);
setIsLoading(false);
}
};
document.body.appendChild(script);
return () => {
if (editorRef.current) {
editorRef.current.destroy();
editorRef.current = null;
}
if (script.parentNode) {
script.parentNode.removeChild(script);
}
if (styleElement.parentNode) {
styleElement.parentNode.removeChild(styleElement);
}
};
}, []);
// 监听外部value变化
React.useEffect(() => {
if (editorRef.current && value) {
try {
const currentValue = editorRef.current.get();
const newValue = JSON.parse(value);
if (JSON.stringify(currentValue) !== JSON.stringify(newValue)) {
editorRef.current.set(newValue);
}
} catch (err) {
console.error('更新JSON数据失败:', err);
}
}
}, [value]);
return (
<div className="w-full">
{isLoading && (
<div className="flex items-center justify-center h-[400px] border rounded-lg">
<div className="text-gray-500">加载中...</div>
</div>
)}
<div
ref={containerRef}
className={`border rounded-lg ${isLoading ? 'hidden' : ''}`}
style={{ height: '400px' }}
/>
</div>
);
}
请
登录后发表观点
这玩意可以用 AI 自定义控件支持吗,感觉狠有用途
顶一个,这种字段应该被源生支持。
顶一个
这个很牛呀,但暂时没有使用到
👍 👍 👍