Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
432 views
in Technique[技术] by (71.8m points)

javascript - 使用react功能组件添加和删除两个集合(Adding and deleting two collections with react functional components)

I want to add two collections with one action.(我想用一个动作添加两个集合。)

First one is file using multer and gridfs-stream and second is just literal with properties based on file.(第一个是使用multer和gridfs-stream的文件,第二个只是具有基于文件属性的文字。) That what I achieved: 1)literal based on file and 2)file uploaded .(我实现的目标: 1)基于文件的文字2)上传的文件 。) In 1)(literal) this fileID property is just the same as _id of 2)(file) and src in 1) is just filename from 2) concatenated with some path.(在1)(字面量)中,此fileID属性与2)(文件)的_id相同,并且1)中的src只是2)中的文件名,并带有一些路径。) And here I have to problems.(在这里,我必须解决问题。) First is that this literal should have more properties, but I have problem with adding them.(首先,此文字应具有更多属性,但是添加它们时遇到问题。) Here's the model(I think that there's isn't any problem, but it contain all props needed):(这是模型(我认为没有任何问题,但其中包含所有需要的道具):)
const mongoose = require('mongoose');
const Schema = mongoose.Schema;

// Create Schema
const FileSchema = new Schema({
  fileID: {
    type: Schema.Types.ObjectId
  },
  src: {
    type: String,
  },
  altText: {
    type: String,
  },
  caption: {
    type: String,
  },
});

module.exports = File = mongoose.model('file', FileSchema);

The most important GET/POST routes(and also DELETE routes for second problem):(最重要的GET / POST路由(以及第二个问题的DELETE路由):)

router.get('/', (req, res) => {
  File.find()
    .sort({ date: -1 })
    .then(files => res.json(files))
});
// @route POST /upload
// @desc  Uploads file to DB
router.post('/', upload.single('file'), auth, (req, res) => {
  const newFile = new File({
    fileID: req.file.id,
    src: 'api/files/image/' + req.file.filename,
    altText: 'No image',
    caption: req.body.caption
  })
  newFile.save()

});

// @route GET /files
// @desc  Display all files in JSON
router.get('/', (req, res) => {
  File.find()
    .sort({ date: -1 })
    .then(files => res.json(files))
});

// @route GET /files/:filename
// @desc  Display single file object
router.get('/:filename', (req, res) => {
  gfs.files.findOne({ filename: req.params.filename }, (err, file) => {
    // Check if file
    if (!file || file.length === 0) {
      return res.status(404).json({
        err: 'No file exists'
      });
    }
    // File exists
    return res.json(file);
  });
});

// @route DELETE /files/:id
// @desc  Delete file
router.delete('/:id', auth, (req, res) => {
  gfs.remove({ _id: req.params.id, root: 'files' }, (err, gridStore) => {
    if (err) {
      return res.status(404).json({ err: err });
    }
  });
  File.findById(req.body.fileID)
    .then(file => file.remove().then(() => res.json({ success: true })))
    .catch(err => res.status(404).json({ success: false }));
});

and my React component most important fragments:(和我的React组件最重要的片段:)

const SliderModal = ({ isAuthenticated, addFile }) => {

  const [modal, setModal] = useState(false);
  const [file, setFile] = useState([]);
  const [slideData, setSlideData] = useState({
    fileID: '',
    src: '',
    altText: '',
    caption: '',
  })


  const toggle = () => {
    setModal(!modal);
  };

  const onChange = e => {
    setFile(e.target.files[0]);
    setSlideData({
      ...slideData,
      [e.target.name]: e.target.value
    });
  };

  const onSubmit = e => {
    e.preventDefault();

    const newFile = new FormData();
    newFile.append('file', file);
    // const { src, altText, caption, fileID } = slideData;

    // const newSlide = {
    //   fileID,
    //   src,
    //   altText,
    //   caption
    // }

    // Add file via addItem action
    addFile(newFile);
    // addFile(newSlide);

    // Close modal
    toggle();
  }

and next part(with use of reactstrap):(下一部分(使用reactstrap):)

<Form onSubmit={onSubmit}>
            <FormGroup>
              {/* <Label for="caption">Caption</Label>
              <Input
                type="text"
                name="caption"
                id="caption"
                placeholder="Caption"
                className="mb-3"
                onChange={onChange}
              /> */}

              <Label for="file">File</Label>
              <Input
                type="file"
                name="name"
                id="file"
                placeholder="Add file"
                onChange={onChange}
              />
              <Button
                color="dark"
                style={{ marginTop: '2rem' }}
                block>
                Add File
                </Button>
            </FormGroup>
          </Form>

in which, when I uncomment I have the text input in my modal in which, when I wrote anything I'm getting error: Error while inputting text The second problem is connected with deleting files.(其中,当我取消注释时,我在模态中输入了文本,当我编写任何内容时,我遇到了错误: 输入文本时出错第二个问题与删除文件有关。)

At this moment I'm able to delete only one of items(literal or file) from database.(目前,我只能从数据库中删除一项(文字或文件)。) Here's DELETE route again: // @route DELETE /files/:id // @desc Delete file router.delete('/:id', auth, (req, res) => { gfs.remove({ _id: req.params.id, root: 'files' }, (err, gridStore) => { if (err) { return res.status(404).json({ err: err }); } }); File.findById(req.body.fileID) .then(file => file.remove().then(() => res.json({ success: true }))) .catch(err => res.status(404).json({ success: false })); });(这里再次是删除路由:// @route DELETE / files /:id // @desc删除文件router.delete('/:id',auth,(req,res)=> {gfs.remove({_id:req。 params.id,root:'files'},(err,gridStore)=> {如果(err){返回res.status(404).json({err:err});}})); File.findById(req .body.fileID).then(file => file.remove()。then(()=> res.json({success:true})))).catch(err => res.status(404).json( {成功:否}));});)

Okay, I see that File.findById isn't good function, but the problem is that I want to delete them simultaneously.(好的,我看到File.findById不是一个好的函数,但是问题是我想同时删除它们。)

That's why in this literal I concluded that fileID property, but I'm really confused about it and can't find a solution.(这就是为什么我用这个字面量得出了fileID属性的原因,但是我对此感到非常困惑,无法找到解决方案。) My idea was to search by this fileID property both and then delete them.(我的想法是同时通过fileID属性进行搜索,然后将其删除。) Here's react function to delete only file(don't look at that is authenticated, that's just that I can delete file only when I'm logged in my app):(这是只删除文件的react函数(不要看已通过身份验证,这就是我只有在登录应用后才能删除文件):)
{files.map(({ fileID}) => (
            < CSSTransition key={fileID} timeout={500} classNames="fade" >
              <ListGroupItem>
                {isAuthenticated ?
                  <Button
                    className="remove-btn"
                    color="danger"
                    size="sm"
                    onClick={onDeleteClick.bind(this, fileID)}
                  >&times;
                  </Button> : null}

              </ListGroupItem>
            </CSSTransition>
          ))}
  ask by Victor translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Ok, I just want to delete two objects with one click.(好的,我只想一键删除两个对象。)

router.delete('/:id', auth, (req, res) => {
  gfs.remove({ _id: req.params.id, root: 'files' }, (err, gridStore) => {
    if (err) {
      return res.status(404).json({ err: err });
    }
  })
  File.findOne(req.body.fileID)
    .then(file => file.remove().then(() => res.json({ success: true })))
    .catch(err => res.status(404).json({ success: false }));
});

Unfortanelly this one delete two objects, but not compatible.(不幸的是,这一删除两个对象,但不兼容。)

This 'File' object have fileID property, which are the same as id in gfs.(此“文件”对象具有fileID属性,该属性与gfs中的id相同。) My will is to delete two objects with the id == fileID.(我的意愿是删除两个ID == fileID的对象。)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...