Mongoose 数据未按预期显示在网页上

问题描述 投票:0回答:1

我正在创建一个使用 mongodb、node.js、express 和 pug 来记笔记的 Web 应用程序。当我加载主页时,笔记按创建日期的顺序排列。当我单击按钮按字母顺序排列笔记时,笔记会在后端正确排序,但仍按创建日期的顺序显示。我的问题是如何让笔记按字母顺序显示。

我的笔记架构:

    const noteSchema = new mongoose.Schema(
      {
title: {
  type: String,
  required: [true, 'You must enter a title.'],
  trim: true,
  unique: [true, 'A note title must be unique.'],
},
noteText: {
  type: String,
  trim: true,
},
itemsArr: [
  {
    type: mongoose.Schema.ObjectId,
    ref: 'Item',
  },
],
slug: String,
createdAt: {
  type: Date,
  default: Date.now(),
  select: false,
},
user: {
  type: mongoose.Schema.ObjectId,
  ref: 'User',
  required: [true, 'A note must belong to a user.'],
},
doneList: [
  {
    type: mongoose.Schema.ObjectId,
    ref: 'Item',
  },
],
    },
  {
toJSON: { virtuals: true },
toObject: { virtuals: true },
},
)

我的后端代码(按字母顺序返回数据)

我的笔记路线 'router.route('/?sort=title').get(noteController.getAllNotes);'

我的API功能

class APIFeatures {
  constructor(query, queryString) {
this.query = query;
this.queryString = queryString;
  }

  filter() {
const queryObj = { ...this.queryString };
const excludeFields = ['page', 'limit', 'sort', 'fields'];
excludeFields.forEach((el) => delete queryObj[el]);

let queryStr = JSON.stringify(queryObj);
queryStr = queryStr.replace(/\b(gt|gte|lt|lte)\b/g, (match) => `$${match}`);
this.query = this.query.find(JSON.parse(queryStr));
return this;
  }

  sort() {
if (this.queryString.sort) {
  const sortBy = this.queryString.sort.split(',').join(' ');
  this.query = this.query.sort(sortBy);
} else {
  this.query = this.query.sort('createdAt _id');
}
return this;
  }

  limitFields() {
if (this.queryString.fields) {
  const fields = this.queryString.fields.split(',').join(' ');
  this.query = this.query.select(fields);
} else {
  this.query = this.query.select('-__v');
}
return this;
  }

  paginate() {
const page = this.queryString.page * 1 || 1;
const limit = this.queryString.limit * 1 || 100;
const skip = (page - 1) * limit;
this.query = this.query.skip(skip).limit(limit);
return this;
  }
}

我的笔记控制器

exports.getAllNotes = catchAsync(async (req, res, next) => {
  const features = new APIFeatures(
Note.findOne({ user: req.user.id }),
req.query,
  )
.filter()
.paginate()
.sort()
.limitFields();
  const notes = await features.query;
  if (notes.length === 0) {
return next(new AppError('No notes for this user were found.', 404));
  }
  res.status(200).json({
status: 'success',
results: notes.length,
notes,
  });
});

当我尝试从网页访问此数据时,它会按创建日期的顺序返回数据。

我的前端代码

我的查看路线 'router.get('/sortByTitle', authController.protect, viewController.getHome);'

我的视图控制器

exports.getHome = catchAsync(async (req, res, next) => {
  try {
res.status(200).render('home', {
  title: 'Home',
  date,
  today,
});
  } catch (error) {
console.log(error);
  }
});

我的哈巴狗 html

extends base    

block content 
    main.main
    
    if user 
        //- - console.log(user.notes)
        .container
            h1.title-welcome= `Welcome ${user.name.split(' ')[0]}` 
            h3.date #{today}
            p.display-text Display options:
                .display-container
                    .display
                        p.text Date Created
                        p.text Alphabetically
                    label.switch
                        input#alpha(type='checkbox')
                        span.slider.round 
                    button.btn.alpha Alpha
            a.btn.add-btn(href='/addNote') Add Note
                i.fa-solid.fa-plus
            form#search-form 
                .form-group#search-form-group     
                    label.form-label(for='search-title') Search:
                    #search-input 
                        input.form-input#search-title(type='text' placeholder='Enter note title...')
                        button.btn.btn-search(title='Search notes') 
                            i.fa-solid.fa-magnifying-glass
            - const noNotes = user.notes.length === 0 ? true : false
            if noNotes
                .notes-container-example 
                    a.btn#btn-exmaple(href='/exampleNote') Example Note
                
            else 
                .notes-container 
                    each note in user.notes 
                        a.btn.show-note(id=`${note.id}` )= note.title
    
    else
        .container
            h1.main-title Note It 
                i.fa-solid.fa-pen-nib
            p.main-text One app for keeping all your notes and lists.
            .home-btn-container 
                a.btn(href='/signup' ) Sign Up 
                a.btn(href='/login' ) Login

我尝试向类名为 alpha 的按钮添加事件侦听器,并调用名为 sortFunction 的函数。这确实检索了我想要的订购数据,但仍然没有将其显示在网页上。

const alphaBtn = document.querySelector('.alpha');
if (alphaBtn) {
  alphaBtn.addEventListener('click', (e) => {
e.preventDefault();
sortfunction();
  });
}

export const sortfunction = async () => {
  try {
const res = await axios('http://127.0.0.1:8080/api/v1/notes/?sort=title');
console.log(res.data);
if (res.data.status === 'success') {
  location.assign('/sortByTitle');
}
  } catch (error) {
console.log(error);
showAlert(
  'error',
  'There was an error sorting your notes. Please try again later.',
    );
  }
};

上面的console.log显示数据正在按照我想要的顺序返回,但我不明白为什么它不能在页面上正确显示。我觉得我的代码中的某个地方可能有冲突。请,任何帮助将不胜感激。

谢谢

javascript node.js express mongoose pug
1个回答
0
投票

这是因为您需要重新加载页面/使用新排序的笔记重新渲染视图。 使用 pug 时使用 Ajax 调用是没有意义的,因此您需要再次渲染视图,但是使用排序的笔记,即 getAllNotes 不应该渲染 json,而是返回排序的笔记 json 到视图渲染/控制器。

要触发此操作,在视图中,您可以添加包含排序查询字符串的链接而不是按钮:

而不是复选框和按钮:

input#alpha(type='checkbox')

添加指向端点的链接,该端点将获取排序的数据,然后重新渲染视图:

a.btn(href='/notes') Sort by date
a.btn(href='/notes?sort=title') Sort by date

因此,您应该创建一个服务于相同视图的单一路由,然后从 getAllNotes 获取笔记,这不会将 json 发送到客户端,而是将排序后的数据返回到控制器以传递到视图。

router.get('/notes', authController.protect, viewController.getHome);

并更改路由处理程序:

// get notes, pass req object to read query, user etc.
const notes = await getAllNotes(req);

// send notes
res.status(200).render('home', {
  title: 'Home',
  date,
  today,
  notes
});

您可以对搜索表单等进行同样的操作。

© www.soinside.com 2019 - 2024. All rights reserved.