todo list операции save/delete/update/fetch
мне нужно закончить server.js чтобы проект заработал. у меня получилось только часть выполнить. остались операции в конце fetch update delete Save, помогите пожалуйста
server.js const express = require("express"); const app = express(); const cors = require("cors"); const session = require("express-session"); const cookieParser = require("cookie-parser"); const whitelist = ['http://localhost', 'http://localhost:3000', 'http://localhost:80']; const corsOptions = { credentials: true, origin: (origin, callback) => { console.log(origin); if ( whitelist.includes(origin) ) { return callback(null, true) } callback(new Error('Not allowed by CORS')); } } app.use(cors()); app.set('trust proxy', 1) app.use(session({ secret: "Wok Tow3l", resave: false, saveUninitialized: true, cookie: { secure: true } })); var sess = { secret: 'Wok Tow3l', cookie: {} } sess.cookie.secure = true // serve secure cookies app.use(session(sess)) app.use(session({ secret: 'Wok Tow3l', cookie: { maxAge: 60000 }})) app.use(cookieParser()); app.get('/ping', function (req, res, next) { res.send('target ' + req.session + ' '); req.sess.destroy(function(err) { }) }) app.post('/ping',(req,res) => { sess = req.session; sess.cookie = req.target; res.end('done'); }); app.use('/', router); app.get("/ping", (req, res) => { res.send('Pong!'); }); /* Save a new Todo */ app.post("/save/:target", (req, resp) => { }); /* Fetch the list of :target Todo item(s) */ app.get("/get/:target", (req, resp) => { // You need to complete this }); /* update a Todo */ app.put("/:target/:id", (req, resp) => { // You need to complete this }); /* delete a Todo */ app.delete("/:target/:id", (req, resp) => { // You need to complete this }); const port = process.env.PORT || 3000; app.listen(port, () => { console.log(`Todo (server) is listening at http://localhost:${port}`); }); |
прикрепляю index.html todo.js
index.html
<!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <link rel="icon" type="image/png" href="images/favicon-16x16.png"> <title>Todo</title> <link rel="stylesheet" href="https://unpkg.com/purecss@2.0.3/build/pure-min.css"> <link rel="stylesheet" href="styles/style.css"/> <script type="module"> import { Todo } from "./modules/todo.js"; const _todo = new Todo(); </script> </head> <body> <main> <section title="Today" class="todoContainer"> <header> <h1>Today</h1> <img class="icon" title="Add Item" width="36" height="36" src="images/plus.png"/> </header><div class="msg"></div> <ul></ul> </section> <section title="Tomorrow" class="todoContainer"> <header> <h1>Tomorrow</h1> <img class="icon" title="Add Item" width="36" height="36" src="images/plus.png"/> </header> <div class="msg"></div> <ul></ul> </section> <section title="Future" class="todoContainer"> <header> <h1>Future</h1> <img class="icon" title="Add Item" width="36" height="36" src="images/plus.png"/> </header> <div class="msg"></div> <ul> <li> <span>Test this out it is even longer...</span> <img class="icon" width="36" height="36" src="images/minus.png"/> <img class="icon" width="36" height="36" src="images/mom.png"/> </li> </ul> </section> </main> </body> </html> todo.js class Todo { constructor() { this.NO_ELEMENT_FOUND = true; this.NO_CHILDREN = true; /* A list of the main containers we have in the application */ this.targets = ['Today','Tomorrow','Future']; window.addEventListener("DOMContentLoaded", (event) => { // Setup the onclick callbacks for each Todo list 'Add' button. this.targets.forEach((target) => { const iconElem = document.querySelector(`section[title='${target}'] img[title='Add Item']`); iconElem.addEventListener("click", event => { this.addTodoItem(target); }); }); }); } /* Each target Todo list has a message div that you can display something into. * Use this method to do only that. * * @target The Todo section DOM element to load * @message The message you want to display */ updateMessageOn(target, message = "") { const ele = document.querySelector(`section[title='${target}'] > header + div.msg`); if ( !ele ) { console.error(`${MESSAGES.en_US.NO_ELEMENT_FOUND} on ${target} for updateMessageOn(target)`); } ele.innerHTML = message; } /* Gets the main section you want ('Today', "Tomorrow" or "Future") * * @returns NULL if the target cannot be found in the DOM */ getTodoContainerElement(target = "") { const todoSectionEle = document.querySelector(`section[title='${target}']`); if ( !todoSectionEle ) { console.error(`${MESSAGES.en_US.NO_ELEMENT_FOUND} on ${target} for getTodoContainerElement(target)`); return null; } return todoSectionEle; } /* Get the unordered list element within your target Todo. * * @target The Todo section DOM element to load * @return A unordered list element, or NULL if not found */ getTodoListFor(target) { const listEle = document.querySelector(`section[title='${target}'] ul`); if ( !listEle ) { console.error(`${MESSAGES.en_US.NO_ELEMENT_FOUND} on ${target} for getTodoListFor(target)`); return null; } return listEle; } /* Adds a new Todo item, if there isn't pending new one's going on right now. * * @target The Todo section DOM element to load */ addTodoItem(target) { if ( this.doesTargetTodoHaveUnsavedItem(target) ) { this.updateMessageOn(target, "Finish the previous one you created first..."); window.setTimeout( () => { this.updateMessageOn(target); }, 1400); return; } const newHtml = `<li unsaved="true" id="${target}_${Date.now()}> <textarea placeholder="Just tab out to save" class="todoItem" onchange="_todo.save(${target}/></textarea> <img class="icon" width="20" height="20" src="images/save_36x36.png"/> </li>`; this.getTodoListFor(target).innerHTML += newHtml; } /* Utility method to look for any unsaved list items in a target Todo list. * * @target The Todo section DOM element to load * @return false - if there are no unsaved list items; true here are unsaved items... */ doesTargetTodoHaveUnsavedItem(target) { let hasSavedItem = false; /** See [url]https://bit.ly/3hsgFbo[/url] for HTMLCollection. It is not an Array by default.. */ let coll = Array.from(this.getTodoListFor(target).children); coll.forEach((child) => { if ( child.getAttribute("unsaved")) { hasSavedItem = true; } }); return hasSavedItem; } /* Checks the containers (Today, Tomorrow & Future). */ /* They should always exist. If not returns FALSE. */ /* They could be empty. That is expected. Returns FALSE */ /* Only returns TRUE when element exists and has kids. */ isListEmpty(target = "Today") { const targetList = document.querySelector(`[title ^= '${target}']`); if ( !targetElement ) { console.error(`Expected parent node (today, tomorrow, future). It is not in the DOM.`); return this.NO_ELEMENT_FOUND; } const children = targetList.children; if ( !children || children.length === 0 ) { return this.NO_CHILDREN; } return true; } addActions(target) { if ( !target) { console.error("Cannot add actions on NULL target"); return; } } } const MESSAGES = { en_US : { NO_ELEMENT_FOUND: "The expected DOM element was not found.", NO_CHILDREN: "" } } export { Todo }; |
Цитата:
/* Save a new Todo */ app.post("/save/:target", (req, resp) => { }); /* Fetch the list of :target Todo item(s) */ app.get("/get/:target", (req, resp) => { // You need to complete this }); /* update a Todo */ app.put("/:target/:id", (req, resp) => { // You need to complete this }); /* delete a Todo */ app.delete("/:target/:id", (req, resp) => { // You need to complete this }); и еще express-session который вроде получилось сделать |
Rise,
подскажите в каком направлении двигаться? |
Rise,
Интерфейс и исходный код были созданы как для вашего пользовательского интерфейса, так и для работы сервера NodeJS с этим приложением. Ваша задача - заполнить недостающие части; Такие как: 1. Редактирование (или обновление ..) существующего элемента Todo. 2. Сохранение / удаление элемента Todo Для этого приложения нет БД. Вам нужно создать литерал объекта для хранения только в рамках сеанса пользователя. Форма объекта должна напоминать этот пример ниже: let data =. [ { id: << уникальный идентификатор из пользовательского интерфейса. Не генерируется сервером. description: << это то, что клиент вставляет для задачи в пользовательском интерфейсе date_deleted: << Если вы поместите здесь дату, она будет удалена. Если null, то не удаляется. type: << это "Today", "Tomorrow" или "Future" }, {...}, {...}, ] Когда пользовательский интерфейс загружается впервые, вам нужно получить все элементы Todo с сервера (если есть ...). И визуализируйте их в соответствующем контейнере. Мы используем обработку Express Session. Итак, если вы закроете страницу и вернетесь, она должна загрузить данные с вашего сервера. |
Ulyana1992,
Про модуль express-session можно почитать на npm. Там написано, что для хранения данных есть специальное свойство req.session. Поэтому ваш массив данных let data = [...], можно представить как req.session.data = [...]. Еще там сказано, что с версии 1.5.0, модуль cookie-parser не нужен. И что cookie: { secure: true } работает с https, но не с http. И так далее. Про модуль cors тоже интересно почитать. Про модуль express можно что-то узнать на его сайте, например, что "/:target/:id" значит req.params, а req.body требуется express.json() или express.urlencoded(). Вообще, есть шаблон express приложения, там какие-то базовые вещи уже сделаны. Но у вас структура папок и файлов какая-то другая, неизвестно зачем. Про сетевые запросы, это fetch(), здесь что-то похожее для вашего задания. В остальном, если не справитесь, написал в личку. |
Rise,
поздно увидела, нo спасибо за материал |
Часовой пояс GMT +3, время: 15:55. |