我在react / typescript应用程序中创建了一个带有textarea组件的表单,您可以在其中将剪贴板中的图像(打印屏幕截图)粘贴到描述字段中。粘贴图像时,您具有粘贴在描述字段中的html代码(例如:http:// localhost:3000 / xxxxx-xxx-xxx-xxx-xxx-xxxxxxxx“ />),并且图像正确显示在我的预览部分。
我的问题是:提交表单时没有保存图像,因为我没有向后端和数据库发送任何信息。但是,我不知道如何将这些粘贴的图像保存到数据库中,因为我只有从事件中检索到的图像URL。网址图片链接应与我从输入事件中检索到的链接相同,以免破坏我的显示。
此外,我使用的是打字稿,因此并非所有npm软件包都可以与我的代码一起使用。
这是我表格的代码:
interface ItemsStates {
item: ItemModel;
isSubmitSuccess: boolean;
}
export const ItemCreation = withGlobalContext(
class extends React.Component<IPropsWithGlobalContext, ItemsStates> {
constructor(props: any) {
super(props);
this.state = {
item: new ItemModel(),
isSubmitSuccess: false,
};
this.handleUserInput= this.handleUserInput.bind(this);
this.submitForm= this.submitForm.bind(this);
}
handleUserInput(event:any) {
const { value, name } = event.target;
const item = {
...this.state.item,
[name]: value,
};
this.setState({ item });
}
submitForm(event:any) {
event.preventDefault();
const item = this.state.item;
axios.post(`http://localhost:3000/api/items`, item)
.then(res => {
console.log( "DATA UPLOADED", res);
console.log("RES DATA",res.data);
this.setState({ isSubmitSuccess: true });
})
.catch(err => {
console.log("ERROR", err);
alert("Sorry! There was an error.");
});
this.setState({ item: new ItemModel() })
}
render() {
const { item, isSubmitSuccess } = this.state as any;
if (isSubmitSuccess) {
return <Redirect to={`/items`} />
}
return(
<>
<h1>Create new item.</h1>
<div>
<form onSubmit={this.submitForm}>
<div>
<label htmlFor="title" >Title</label>
<div>
<input type="text" name="title" onChange={this.handleUserInput} value={item.title} />
</div>
</div>
<Textarea onUserInput={this.handleUserInput} value={item.description} creation={true} />
<div>
<label htmlFor="author">Author</label>
<div>
<input type="text" name="author" onChange={this.handleUserInput} value={item.author} />
</div>
</div>
</form>
<div>
<button onClick={this.submitForm}>Submit</button>
</div>
</div>
</>
);
}
}
);
这是我的textarea组件的代码:
interface ITextareaProps {
onUserInput: any;
value:string;
}
interface ITextareaStates {
description: string;
}
export const Textarea = withGlobalContext(
class extends React.Component<ITextareaProps, ITextareaStates> {
static getDerivedStateFromProps(props:any, state:any) {
if ( !props.creation && (state.description === "" || state.description === undefined) ) {
return { description: props.value };
}
return null;
}
constructor(props: any) {
super(props);
this.state = {
description: "",
};
this.sendUserInput = this.sendUserInput.bind(this);
}
sendUserInput(event:any) {
this.setState({
description: event.target.value,
});
this.props.onUserInput(event);
}
handleImagePaste = (dataReceived:any) => {
for ( const index in dataReceived) {
if (dataReceived[index].kind === 'file') {
const blob = URL.createObjectURL(dataReceived[index].getAsFile());
const balise = `<img src="${blob}" />`;
this.setState({
description: `${this.state.description} ${ balise}`,
});
}
}
}
render() {
return (
<>
<div>
<label htmlFor="description">Description</label>
<div>
<Clipboard handlePaste={this.handleImagePaste}>
<textarea name="description" value={this.state.description} onChange={this.sendUserInput} />
</Clipboard>
</div>
</div>
<div>
<label htmlFor="description">Preview</label>
<div style = {{whiteSpace: "pre-wrap"}} dangerouslySetInnerHTML={{ __html: this.state.description }}/>
</div>
</>
);
}
}
);
还有剪贴板组件的代码:
interface IClipboardProps {
handlePaste: any;
}
export const Clipboard = withGlobalContext(
class extends React.Component<IClipboardProps> {
dropRef = React.createRef<HTMLDivElement>()
constructor(props: any) {
super(props);
}
handlePaste = (e: any) => {
if (e.clipboardData) {
this.props.handlePaste(e.clipboardData.items)
}
}
componentDidMount() {
const div: any = this.dropRef.current
div.addEventListener('paste', this.handlePaste)
}
componentWillUnmount() {
const div: any = this.dropRef.current
div.removeEventListener('paste', this.handlePaste)
}
render() {
return (
<div ref={this.dropRef}>{this.props.children}</div>
)
}
}
);
编辑 对于后端,我正在使用招摇。 因此,这是我在数据库(位于我的项目控制器中)中创建新项目的功能:
const Item= require("../../models/item-model.js");
function create(req, res) {
const { title, description, author } = req.swagger.params.item.value;
Item.create ({title, description, author})
.then(itemDoc => res.status(201).json(itemDoc))
.catch(err => {
console.log("ERROR", err)
res.status(404).json(err.message)});
}
这是我后端的Item模型:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const itemSchema = new Schema({
title: { type: String, required: true },
description: { type: String, required: true },
author: { type: String, required: true }
}, {
timestamps: true
});
const Item = mongoose.model("Item", itemSchema);
module.exports = Item;
有人可以帮我吗?