【问题标题】:My web app is duplicating user input for post, not showing user deleted unless page refresh for delete我的网络应用程序正在复制用户输入以进行发布,除非页面刷新删除,否则不显示用户已删除
【发布时间】:2018-10-16 04:41:21
【问题描述】:

我有一个用 Javascript 编写的小应用程序,它是一个待办事项列表。前端是简单的 Javascript,它从数组中获取数据,然后允许用户向数组中添加项目(发布数据)。当他们点击一个项目时,它应该被删除

现在,它有点起作用了。所以当用户输入一个项目并按下回车或点击提交时,它会列出两次该项目?!

当用户单击要删除的项目时,它仅在页面刷新时删除 (F5)。 location.reload() 方法似乎没有触发,或者没有成功注册

这是前端,显示重复:

这里是控制post和delete的js(todo_list.js):

//These are ajax requests
//in the controller post method we will be using this code
$(document).ready(function(){
//when click submit
  $('form').on('submit', function(){
//create item
      let item = $('form input');
      //create todo with value from item above
      //add to data array in the controller
      let todo = {item: item.val()};
//send post request to post in controller
      $.ajax({
        type: 'POST',
        url: '/todo',
        //pass todo as data
        data: todo,
        success: function(data){
          //do something with the data via front-end framework
//reload page when new item is added
          location.reload();
        }
      });

      return false;

  });

  $('li').on('click', function(){
    //replace spaces with hyphens
      var item = $(this).text().replace(/ /g, '-');
      $.ajax({
        type: 'DELETE',
        url: '/todo/' + item,
        success: function(data){
          location.reload();
        }
      });
  });    
});

这是网页的 ejs 文件 (todo.ejs):

<html>
<head>
  <title>To-do list</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.1/jquery.min.js"></script>
  <!-- below works because of the middleware setting for static files -->
  <script src="/assets/todo_list.js"></script>
  <link href="/assets/styles_example_app.css" rel="stylesheet" type="text/css" />
</head>
<body>
  <h1>My todo list</h1>
  <div id="todo-table">
    <form method="POST">
      <input type = "text" name="item" placeholder="Add new item..." required />
      <button type = "submit">Add items</button>
    </form>
    <ul>
        <% for(let i = 0; i < todos.length; i++){ %>
          <li><%= todos[i].item %></li>
        <% } %>
    </ul>
  </div>
</body>
<script src="/assets/todo_list.js"></script>
</html>

在上面,需要for循环来显示数组(数据)中的现有项,这里是控制器:

const bodyParser = require('body-parser');

//storing some data to display on the webpage. This is the array we're working with

let data = [{item: 'get milk'}, {item: 'walk dog'}, {item: 'kick Joey'}];

let urlencodedParser = bodyParser.urlencoded({extended: false});


module.exports = function(app){
  //now we're exporting and calling in app.js, we can make the routes
  app.get('/todo', function(req, res){
    //render a get request when user visit /todo in browser
    //pass the data from the above data object onto the page
    res.render('todo', {todos: data});
  });

  //handler for post request for when user enters to do list item todo_list.js
  app.post('/todo', urlencodedParser, function(req, res){
      //grab data from array and push user input data to array
      //added new item to data array
      data.push(req.body);
      //once added, render page
      res.redirect('/todo');
  });
  //handler for deleting the files
  app.delete('/todo/:item', function(req,res){
    //filter out item that we're trying to delete
    data = data.filter(function(todo){
      // bottom is returning true or false
      // if false, remove from array
      return todo.item.replace(/ /g, '-') !== req.params.item;
      res.redirect('/todo');
    })
  });
} 

我很困惑的是如何复制输入的帖子数据,以及为什么单击删除的项目时不会重新加载页面。如果我手动重新加载,它们会被删除。我觉得我错过了一些小东西,因为它很有效,虽然很糟糕

有人有什么建议吗?

到目前为止,我已经尝试将 jquery 调用更改为 google(我在这里找到了一个建议),也在 EJS 文件中将表单标签中的 post 指定为方法

谢谢

【问题讨论】:

  • 对不起,如果这看起来有点业余,这是我的第一个项目,所以 cmets 将让我记住它在做什么以及它是如何联系在一起的
  • 您确定调用了“DELETE”成功回调吗?您是否尝试在此处放置断点,或者至少在控制台日志中放置?
  • 我刚刚尝试添加一个 console.log -> "success: function(data){ location.reload(); console.log('it deleted');"它不会登录到控制台,但是当我重新加载页面时,网页中点击的项目消失了
  • 尝试在 DELETE 中添加错误回调,并在其中执行 console.log(arguments),这样我们就可以查看它是否失败以及原因。此外,网络选项卡,检查“保留日志”并查看“删除”api 是否返回了 200,我对此表示怀疑。我认为这就是原因。
  • location.reload(); 将刷新页面,因此您在此之后添加的任何内容都无关紧要(您可能短暂地看到控制台日志,但值得怀疑) .

标签: javascript jquery node.js ajax ejs


【解决方案1】:

快速解决方案(hack 不是真正的解决方案):

$.ajax({
    type: 'DELETE',
    url: '/todo/' + item,
    always: function(data){
      location.reload();
    }
  });

上述方法可以工作,因为无论响应是什么,它都会调用回调,但这不是正确的解决方案,正确的解决方案是确保根据 HTTP 状态代码返回正确的响应代码:https://en.wikipedia.org/wiki/List_of_HTTP_status_codes并通过成功/错误回调正确处理。

第三,您使用 ajax 来避免重新加载,例如:您可以在每次 api 调用时返回最新的项目列表,并在每次 api 调用后重新渲染组件,而不是重新加载。

【讨论】:

  • 奇怪的是,这并没有重新加载 li 项目。我尝试更改控制器以呈现帖子和删除页面作为测试,但如果您使用 res.render(),它不会自动刷新列表。使用 res.redirect 适用于 POST 但不适用于删除。这很令人困惑
  • 在你的服务器上,而不是 res.redirect('/todo');做 res.send("OK"),这应该返回 200 并调用成功回调,是这样做的吗?
  • 不奇怪,在网络中,当单击一个项目时,状态为“(待定)”。你所说的关于捕获响应的内容对我来说很有意义。会不会是发起者是 jquery.min.js:4,但是在我的 ejs 文件中我使用的是 1.12.1 版本?废话,我试过更新热链接,没有运气
  • 我怀疑发起人与它有什么关系。对不起,我的想法用完了。我认为您必须首先专注于从服务器返回正确的状态代码(这可以帮助:expressjs.com/en/api.html#app.delete.method),之后,所有回调都会正常工作。找到解决方案后告诉我们。
  • 感谢您为我指明正确的方向,感谢您抽出宝贵的时间
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-17
  • 2015-06-08
相关资源
最近更新 更多