0

我有一个可以完美运行并保持表单更新的应用程序,但前提是我重新加载 DOM。当有人单击提交按钮时,是否可以使用新输入或用户修改的数据更新表单而无需重新加载?

服务器代码:

"use strict";

const DATA_HANDLER = require('./node/DataHandler');

class app {
     constructor() {
          this.ejsData = null;
          this.nedbData = new DATA_HANDLER();
          this.nedbData.loadData((docs) => {
               this.ejsData = docs;
          });
          this.loadServer();
     }

     loadServer() {
          const HTTP = require('http'),
               EJS = require('ejs'),
               PORT = 1337,
               SERVER = HTTP.createServer((req, res) => {
                    let httpHandler = (err, str, contentType) => {
                         if (err) {
                              res.writeHead(500, { 'Content-Type': 'text/plain' });
                              res.end('An error has occurred: ' + err.message);
                         } else if (contentType.indexOf('image') >= 0) {
                              res.writeHead(200, {'Content-Type': contentType});
                              res.end(str, 'binary');
                         } else if (contentType.indexOf('html') >= 0) {
                              res.writeHead(200, { 'Content-Type': contentType });
                              res.end(EJS.render(str, {
                                   data: this.ejsData,
                                   filename: 'index.ejs' }));
                         } else {
                              res.writeHead(200, { 'Content-Type': contentType });
                              res.end(str, 'utf-8');
                         }
                    };

                    if (req.method == 'POST') {
                         if (req.headers['x-requested-with'] === 'XMLHttpRequest') {
                              this.loadData(req, res, 0);
                         } else if (req.headers['x-requested-load'] === 'XMLHttpRequest1') {
                              this.loadData(req, res, 1);
                         } else {
                              console.log("[405] " + req.method + " to " + req.url);
                              res.writeHead(405, "Method not supported", { 'Content-Type': 'text/html' });
                              res.end('<html><head><title>405 - Method not supported</title></head><body><h1>Method not supported.</h1></body></html>');
                         }
                    } else if (req.url.indexOf('/javascripts/') >= 0) {
                         this.render(req.url.slice(1), 'application/ecmascript', httpHandler, 'utf-8');
                    } else if (req.url.indexOf('/css/') >= 0) {
                         this.render(req.url.slice(1), 'text/css', httpHandler, 'utf-8');
                    } else if (req.url.indexOf('/images/') >= 0) {
                         this.render(req.url.slice(1), 'image/jpeg', httpHandler, 'binary');
                    } else {
                         this.render('public/views/index.ejs', 'text/html', httpHandler, 'utf-8');
                    }
               }).listen(PORT, _ => console.log('-= Work Order Server Listening at http://127.0.0.1:' + PORT + ' =-'));
     }

     render(path, contentType, callback, encoding) {
          const FS = require('fs');
          FS.readFile(__dirname + '/' + path, encoding ? encoding : 'utf-8', (err, str) => { // ternary
               callback(err, str, contentType);
          });
     }

     loadData(req, res, whichAjax) {
          if (whichAjax === 1) {
               const FORMIDABLE = require('formidable');
               let formData = {};
               new FORMIDABLE.IncomingForm().parse(req).on('field', (field, name) => {
                    formData[field] = name;
               }).on('error', (err) => {
                    next(err);
               }).on('end', () => {
                    this.nedbData.queryData(formData);
               });
          }
          this.nedbData.loadData((docs) => {
               let jsonDocs = JSON.stringify(docs);
               res.writeHead(200, {'content-type': 'application/json'});
               res.end(jsonDocs);
               this.ejsData = docs;
          });
     }
}

module.exports = app;

数据处理器:

 "use strict";

    const DATASTORE = require('nedb');
    let DB = new DATASTORE({ filename: './data/workorder_db.json', autoload: true });
         this.data = [];

    class DataHandler {
        constructor() {
              DB.loadDatabase();
        }

         loadData(callback) {
              DB.find({}, (err, docs) => {
                   if (docs.length != null) {
                        callback(docs);
                   }
              });
         }

         updateData(data) {
              DB.update({ _id: data.id }, { building: data.building
                   , roomNumber: data.roomNumber
                   , submitter: data.submitter
                   , problemDesc: data.problemDesc
                   , assigned: data.assigned
                   , completed: data.completed
                   , status: data.status
                   , date: data.date
              }, { upsert: true,
                   returnUpdatedDocs: true });
         }

         addData(data) {
              delete data.id;  // remove id field out of JSON parameter
              DB.insert(data);
         }

         queryData(data) {
              DB.findOne({ _id: data.id }, (err, docs) => {
                   if (docs == null) {
                        this.addData(data);
                   } else {
                        this.updateData(data);
                   }
              });
         }
    }

    module.exports = DataHandler;

EJS 文件:

<div class="row">
    <div class="small-12 columns">
        <h4>Current Work:</h4>
        <table>
            <% if (data.length > 0) { %>
                <tr>
                    <td><strong>Date</strong></td>
                    <td><strong>Building</strong></td>
                    <td><strong>Room #</strong></td>
                    <td><strong>Challenge</strong></td>
                    <td><strong>Assignment</strong></td>
                    <td><strong>Status</strong></td>
                </tr>
                <% for (let i = 0; i < data.length; i++) { %>
                    <tr>
                        <td><%= data[i].date %></td>
                        <td><%= data[i].building %></td>
                        <td><%= data[i].roomNumber %></td>
                        <td><%= data[i].problemDesc %></td>
                        <td><%= data[i].assigned %></td>
                        <td><%= data[i].status %></td>
                    </tr>
                <% } %>
            <% } %>
        </table>
    </div>
</div>
4

1 回答 1

1

使用 Ajax,以下是使表单保持最新的一般方案:

  1. 从客户端到服务器进行 Ajax 调用,询问服务器是否有任何更新的数据。
  2. 如果服务器已更新数据,它会返回该数据(可能是 JSON 格式)。
  3. 当客户端接收到数据时,它可以使用 DOM 操作函数将更改的数据直接插入到现有表单中(无需重新加载)。
  4. 然后,客户端可以设置一个计时器并以某个固定的时间间隔重复此过程。

使用 webSockets,以下是使您的表单保持最新的一般方案:

  1. 作为页面加载的一部分,页面创建到服务器的 webSocket 连接。
  2. 在服务器上,只要有新的表单数据可用,服务器就可以通过 webSocket 将该数据发送到连接的客户端。
  3. 当客户端通过 webSocket(与上述选项相同的 JSON)接收数据时,它可以使用 DOM 操作函数将更改的数据直接插入现有表单(无需重新加载)。

因为客户端/服务器与 webSocket 连续连接,所以不需要像 Ajax 选项中那样的计时器或连续轮询。


您不显示表单 HTML,因此我们无法具体建议如何进行表单操作,但这里有一个示例:

<form>
    <input id="someField">
</form>

// put new value into input field
document.getElementById("someField").value = myNewValue;
于 2016-05-25T15:57:08.230 回答