NextJS / MongoDB - 将数据从一个集合分配到另一个集合

NextJS / MongoDB - assign data from one collection into another

我知道这个问题经常被问到,但我尝试使用 react-hook-form 和自定义 selector 工具来解决它,所以我没有找到那个案例。主要目标是将员工集合中的数据分配给公司集合。 我的模型看起来像这样(缩短):

const companySchema = new mongoose.Schema(
  {
    name: {
      type: String,
      required: true,
    },
    employees: [
      {
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Employee',
      },
    ],  
  }
);
const employeeSchema = new mongoose.Schema(
  {
    firstName: {
      type: String,
      required: true,
    },
    lastName: {
      type: String,
      required: true,
    },
  }
);

我的创建页面是这样的:

export default function CreateSet() {
  const { register, handleSubmit } = useForm();
  const router = useRouter();
  const { redirect } = router.query;
  const { state, dispatch } = useContext(Store);
  const { vendorInfo } = state;
  useEffect(() => {
    if (!vendorInfo) {
      router.push('/');
    }
  }, []);

  const submitHandler = async ({
    name,
    employees: [],
    },
  }) => {
    try {
      const { data } = await axios.post(
        '/api/company/',
        {
          name,
          employees: [],
        },
        {
          headers: { authorization: `Bearer ${vendorInfo.token}` },
        }
      );
      dispatch({ type: 'COMPANY_CREATE', payload: data });
      router.push(redirect || '/vendor/');
    } catch (err) {
      console.log(getError(err));
    }
  };
  return (
    <div title='CompanyCreation' className={styles.register_container}>
      <form onSubmit={handleSubmit(submitHandler)}>
        <h1>Create Company</h1>
        <ul>
          <li>
            <input
              id='name'
              label='name'
              placeholder='Name'
              {...register('name', { required: true })}
            />
          </li>
          <li>
            <p>Employees:</p>
            <EmployeeSelector employees={employees} />
          </li>
          <li>
            <button type='submit'>Create</button>
          </li>
        </ul>
      </form>
    </div>
  );
}

这是 EmployeeSelector 组件:

import React, { useEffect, useReducer, useContext, useState } from 'react';
import axios from 'axios';
import Table from 'react-bootstrap/Table';
import dynamic from 'next/dynamic';
import { useRouter } from 'next/router';
import { getError } from '../utils/error';
import { Store } from '../utils/store';

function reducer(state, action) {
  switch (action.type) {
    case 'FETCH_REQUEST':
      return { ...state, loading: true, error: '' };
    case 'FETCH_SUCCESS':
      return { ...state, loading: false, employees: action.payload, error: '' };
    case 'FETCH_FAIL':
      return { ...state, loading: false, error: action.payload };

    default:
      state;
  }
}

function EmployeeList() {
  const { state } = useContext(Store);
  const router = useRouter();
  const { vendorInfo } = state;
  const [employee, setEmployee] = useState([]);

  const [{ loading, error, products }, dispatch] = useReducer(reducer, {
    loading: true,
    employees: [],
    error: '',
  });

  //selected employees
  const selectHandler = (e) => {
    e.preventDefault;
    e.target.value .....????

};

  useEffect(() => {
    const fetchData = async () => {
      try {
        dispatch({ type: 'FETCH_REQUEST' });
        const { data } = await axios.get(`/api/employee`, {
          headers: { authorization: `Bearer ${vendorInfo.token}` },
        });
        dispatch({ type: 'FETCH_SUCCESS', payload: data });
      } catch (err) {
        dispatch({ type: 'FETCH_FAIL', payload: getError(err) });
      }
    };

    fetchData();
  }, []);

  return (
    <div title='EmployeeList'>
      {loading ? (
        <p>Loading</p>
      ) : error ? (
        <p>{error}</p>
      ) : (
        <Table striped bordered>
          <thead>
            <tr>
              <th>Select</th>
              <th>First name</th>
              <th>Last name</th>
            </tr>
          </thead>
          <tbody>
            {employees.map((employee) => (
              <tr key={employee._id}>
                <td>
                  <input
                    id='employees'
                    label='employees'
                    type: checkbox
                    {...register('employees', { required: true })}
                    onClick={selectHandler}
                  />
                </td>
                <td>{employee.firstName}</td>
                <td>{employee.lastName}</td>
              </tr>
            ))}
          </tbody>
        </Table>
      )}
    </div>
  );
}

export default dynamic(() => Promise.resolve(EmployeeList), { ssr: false });

所以我试图实现的是让用户能够从列表中 select 一名或多名员工并将他们分配给公司。我m realy not sure how to make it - my thought was to overgive the values into the state of EmployeeSelector and from there fetch these and fire them into the companys collection. Maybe this is the wrong way, anyway I don不知道如何实现这个策略,所以 selectorHandler 看起来确实如此。 有人会告诉我处理这种情况的正确方法来帮助我吗? 谢谢大家!

要将数据从一个 collection 分配给另一个,您需要创建一个 API endpoint (nodejs) - 想象一下 您已经创建了 /api/getComplexData .js 文件

使用此端点,您可以编写复杂的“查询”以从任何集合中获取任何数据。您在 API endpoint 进行的所有数据库操作。查看 nextjs/mongodb 个示例 (one, two)

查看复杂的示例,例如 $lookup。不要在前端覆盖数据。您可以使用 mongodb queries

“合并”、“修改”和删除任何类型的数据