首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将从Mongodb嵌入的对象数组中的单个对象显示到Nextjs应用程序中

如何将从Mongodb嵌入的对象数组中的单个对象显示到Nextjs应用程序中
EN

Stack Overflow用户
提问于 2022-08-05 10:12:35
回答 1查看 33关注 0票数 0

所以我面临着一个问题。我有一个嵌入式数组,如下所示,其中包括一个商店和两个产品:

代码语言:javascript
复制
{
      restaurantName: 'Rolex Papa',
      restaurantSlug: 'rolex-papa',
      restaurantLogo: '/images/rolexpapa.jpg',
      products: [
        {
          name: 'Rolex2',
          slug: 'rolex2',
          category: 'rolex',
          image: '/images/pork2.jpg',
          price: 2000,
          brand: 'Papa',
          rating: 4.5,
          numReviews: 8,
          countInStock: 22,
          description: 'A very nice and popular product',
          extraOptions: [
            {
              text: 'Tomatoes',
              price: 20,
            },
            {
              text: 'Soda',
              price: 30,
            },
          ],
        },
        {
          name: 'Rolex1',
          slug: 'rolex1',
          category: 'rolex',
          image: '/images/pork1.jpg',
          price: 6000,
          brand: 'Nike',
          rating: 4.5,
          numReviews: 8,
          countInStock: 22,
          description: 'A very nice and popular product',
          extraOptions: [
            {
              text: 'Tomatoes',
              price: 20,
            },
            {
              text: 'Soda',
              price: 30,
            },
          ],
        },
       
      ],
    },

我已经成功地创建了一个单一的商店页面,一切似乎都运行良好。我可以获取商店中的所有产品,然后在restaurantSlug.js页面中获取所有必要的存储信息。见下文:

代码语言:javascript
复制
import React from 'react';
import Restaurant from '../../models/Restaurant';
import db from '../../utils/db';
import Layout from '../../components/Layout';
import Banner from '../../components/Banner';
import ProductItem from '../../components/ProductItem';
import { useContext } from 'react';
import { Store } from '../../utils/Store';
import { toast } from 'react-toastify';

const RestaurantScreen = (props) => {
  const { restaurant } = props;

  const { state, dispatch } = useContext(Store);
  const { cart } = state;

  const addToCartHandler = async (product) => {
    const existItem = cart.cartItems.find((x) => x.slug === product.slug);
    const quantity = existItem ? existItem.quantity + 1 : 1;

    dispatch({ type: 'CART_ADD_ITEM', payload: { ...product, quantity } });

    toast.success('Product added to the cart');
  };

  return (
    <Layout title={restaurant.restaurantName}>
      <div>
        <div className="container p-2 mx-auto">
          <div className="flex flex-row flex-wrap">
            <div className="hidden md:block sm:w-2/3 md:w-2.8/4 pt-1 px-2 border-gray-200 shadow-md border-2 m-1 rounded-md">
              <Banner />
            </div>

            <div class="ml-7 shadow-lg rounded-2xl w-80 bg-white dark:bg-gray-800">
              <img
                alt="profil"
                src={restaurant.restaurantLogo}
                className="rounded-t-lg h-[150px] md:h-[230px] w-full mb-4"
              />
              <div class="flex flex-col items-center justify-center p-4 -mt-16">
                <a href="#" class="md:hidden block relative">
                  <img
                    alt="profil"
                    src={restaurant.restaurantLogo}
                    class="mx-auto object-cover rounded-full h-16 w-16  border-2 border-white dark:border-gray-800"
                  />
                </a>
                <p class="relative text-gray-800 dark:text-white text-xl font-medium mt-9">
                  {restaurant.restaurantName}
                </p>

                <div class="rounded-lg p-2 w-full mt-2"></div>
              </div>
              <div className="flex justify-around pb-2">
                <p className="py-2 px-4 text-sm font-medium text-center text-white bg-blue-700 rounded-lg hover:bg-blue-900 focus:ring-4 focus:ring-blue-300 dark:bg-purple-600 dark:hover:bg-purple-700 dark:focus:ring-purple-800 mr-4">
                  Contact Us
                </p>
              </div>
            </div>
          </div>
        </div>

        <div className="grid grid-cols-1 gap-4 md:grid-cols-3 lg:grid-cols-4">
          {restaurant.products.map((product) => (
            <div>
              <ProductItem
                product={product}
                key={product.slug}
                addToCartHandler={addToCartHandler}
              />
            </div>
          ))}
        </div>
      </div>
    </Layout>
  );
};

export default RestaurantScreen;

export async function getServerSideProps(context) {
  const { params } = context;
  const { restaurantSlug } = params;

  await db.connect();
  const restaurant = await Restaurant.findOne({ restaurantSlug }).lean();
  await db.disconnect();
  return {
    props: {
      restaurant: JSON.parse(JSON.stringify(restaurant)),
    },
  };
}

此时,产品在商店中正确显示(餐厅屏幕)。但困扰的问题是,为什么当我到达单一产品页面时,产品没有可用。下面是单个产品页面的代码,即

/产品/鼻涕虫。

代码语言:javascript
复制
    import Image from 'next/image';
import Link from 'next/link';
import { useRouter } from 'next/router';
import React, { useContext } from 'react';
import Layout from '../../components/Layout';
import db from '../../utils/db';
import { Store } from '../../utils/Store';
import Restaurant from '../../models/Restaurant';

export default function ProductScreen({ product }) {
  const { state, dispatch } = useContext(Store);

  const router = useRouter();

  if (!product) {
    return <Layout title="Product Not Found">Product Not Found</Layout>;
  }

  return (
    <Layout title={product.name}>
      <div className="py-2">
        <Link href="/">Back to Products</Link>
      </div>
      <div className="grid md:grid-cols-4 md:gap-3">
        <div className="md:col-span-2">
          <Image
            src={product.image}
            alt={product.name}
            width={640}
            height={640}
            layout="responsive"
          ></Image>
        </div>
        <div>
          <ul>
            <li>
              <h1 className="text-lg">{product.name}</h1>
            </li>
            <li>Category: {product.category}</li>
            <li>Brand: {product.brand}</li>
            <li>
              {product.rating} of {product.numReviews} reviews
            </li>
            <li>Description: {product.description}</li>
          </ul>
        </div>
        <div>
          <div className="card p-5">
            <div className="mb-2 flex justify-between">
              <div>Price</div>
              <div>${product.price}</div>
            </div>
            <div className="mb-2 flex justify-between">
              <div>Status</div>
              <div>
                {product.countInStock > 0 ? 'In Stock' : 'Out of Stock'}
              </div>
            </div>
            <button
              className="primary-button w-full"
              onClick={addToCartHandler}
            >
              Add To Cart
            </button>
          </div>
        </div>
      </div>
    </Layout>
  );
}

export async function getServerSideProps(context) {
  const { params } = context;
  const { products } = params;

  await db.connect();
  const product = await Restaurant.findOne({ products }).lean();

  return {
    props: {
      product: JSON.parse(JSON.stringify(product)),
    },
  };
}

为此,我将mongodb与nextjs结合使用。请参阅餐厅的模型:

代码语言:javascript
复制
import mongoose from 'mongoose';

const restaurantSchema = new mongoose.Schema({
  restaurantName: { type: String, required: true },
  restaurantSlug: { type: String, required: true, unique: true },
  restaurantLogo: { type: String, required: true },
  products: [
    {
      name: { type: String, required: true },
      slug: { type: String, required: true, unique: true },
      category: { type: String, required: true },
      image: { type: String, required: true },
      price: { type: Number, required: true },
      brand: { type: String, required: true },
      rating: { type: Number, required: true, default: 0 },
      numReviews: { type: Number, required: true, default: 0 },
      countInStock: { type: Number, required: true, default: 0 },
      description: { type: String, required: true },
      extraOptions: {
        type: [
          {
            text: { type: String, required: true },
            price: { type: Number, required: true },
          },
        ],
      },
    },
  ],
});

const Restaurant =
  mongoose.models.Restaurant || mongoose.model('Restaurant', restaurantSchema);
export default Restaurant;

对此的任何帮助都将受到高度赞赏。非常感谢。

EN

回答 1

Stack Overflow用户

发布于 2022-08-08 17:27:02

在我看来你把鼻涕虫弄混了。此外,您也不必JSON.parse(JSON.stringify(.))数据。您必须使用$elemMatch (文档)。试着使用以下方法:

代码语言:javascript
复制
export async function getServerSideProps({ params }) {
  await db.connect();
  const product = await Restaurant.findOne({ restaurantSlug: params.restaurantSlug, products: {
    $elemMatch: {
      slug: params.slug
    }
} });

  return {
    props: {
      product
    },
  };
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73248135

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档