在脚本运行完成后允许单击链接

时间:2017-10-24 08:47:29

标签: javascript html node.js express ejs

我试图找到一种方法,只有在特定功能完成运行后才允许用户点击链接。所以在我的情况下我有ejs模板,其中parapgraphs中有两个链接。单击第一个("运行python")激活需要一些时间才能完成的脚本。然后只有在它完成后(所以"完成" - 来自行:console.log('finished')打印在控制台上)下一个链接(&# 34;参见表格")可点击(或取消隐藏或类似的东西)。

<h1>Search for a movie</h1>

<form action="results" method="GET">
    <input type="text" placeholder="search term" name="search">
    <input type="submit">
</form>

<p><a href="/run"> Run python </a></p>
<p><a href="/data"> See the table </a></p>

这是app.js代码

var express = require("express")
var app = express()
var request = require("request")
var PythonShell = require('python-shell');
app.set("view engine", "ejs")
app.engine('html', require('ejs').renderFile);

var thelist =[]

app.get("/", function(req, res){
    res.render("search")
})

var jsondata = ""


app.get("/results", function(req, res){
    var query = req.query.search
    var url = "http://www.omdbapi.com/?s=" + query + "&type=series&apikey=thewdb"

    request(url, function(error, response, body){
        if(!error && response.statusCode == 200){
            var data = JSON.parse(body)
            res.render("results", {data: data})
        }    
    })
})

app.get('/data', function(req, res) {
    //viewname can include or omit the filename extension
    res.render(__dirname + '/well.html'); 
});


app.get("/show/:id", function (req, res) {
    var id = req.params.id;
    thelist.push(id)
    console.log(thelist);
    res.redirect('/')
});

app.get("/run", function(req, res) {
            var pyshell = new PythonShell('script2.py');
            pyshell.send(JSON.stringify(thelist))
            pyshell.on('message', function (message) {
    // received a message sent from the Python script (a simple "print" statement)
            jsondata += message
            });

// end the input stream and allow the process to exit
            pyshell.end(function (err) {
             if (err){
               throw err;
                };

            console.log('finished');
            });
            res.redirect('/')
            thelist = []
});

app.listen(process.env.PORT, process.env.IP, function(){
    console.log("Movie App has started!!!");
})

5 个答案:

答案 0 :(得分:3)

<强>摘要

应该通过使用AJAX调用来完成。您可以返回一些表示作业成功/错误状态的JSON数据,而不是在/run中使用重定向。

点击Run python后,它会运行AJAX调用,而不是将页面重定向到/

在AJAX调用的OnSuccess上,您可以启用查看表格。

<强>代码

HTML

<p><a id="run" href="/run"> Run python </a></p>
<p><a id="show-data" href="/data" style="pointer-events:none;"> See the table </a></p>

前端Javascript

$(function() {
  $('#run').click(function(event) {
     event.preventDefault();
     $.get('/run', function() {
       $('#show-data').css('pointer-events', 'all');
     });
  });
});

的NodeJS

app.get("/run", function(req, res) {
  ...
  // res.redirect('/');
  res.json({ success: true });
});

答案 1 :(得分:3)

你可以用ajax来做,正如埃米尔在他的回答中所说, 但由于您使用的是 ejs 模板引擎,为什么不使用它呢? (您只需将.html模板文件扩展名更改为.ejs)。

此外,我认为您最好的选择是不使用res.redirect 最好使用res.render并将参数传递给视图,默认设置为false

一个基本的例子:

server.js

// ...
app.get("/", function (req, res) {
  res.render("search", { active: false });
})

// ...
app.get("/run", function (req, res) {
  // ...
  pyshell.end(function (err) {
    if (err) throw err;
    console.log('finished');
    res.render("search", { active: true });
  });
});

search.ejs

<p><a href="/run">Run python</a></p>
<p>
  <%if (active) { %>
    <a href="/data">See the table</a>
  <% } else { %>
    See the table
  <% } %>
</p>

现在See the table链接只有在python脚本完成时才可以点击。

答案 2 :(得分:1)

U可以通过使用防止功能Jquery

来阻止链接
 $("a").click(function() {
        if (status == "1") {
           return true;

        } else {
           return false;
           e.preventDefault();
        }
     });

这是我用来阻止用户在不运行功能的情况下导航到其他页面的功能。

我初始化了一个名为status的变量,其值为= 0

然后,一旦函数成功,我就会增加变量。

因此,如果状态为0,那么URL将无法工作,在完成该功能后,状态将增加到1,因此如果条件为真,则返回true语句。如果不是,它将返回false语句,并且将使用e.preventDefault()

来阻止它

答案 3 :(得分:-1)

为什么不尝试socket.io? 这是简化的代码,但功能齐全......

(注意:“msg”对象仅作为示例,仅供进一步使用)

<强>的index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Title</title>
</head>

<body>
  <h1>Search for a movie</h1>
  <p><a href="#" onclick="runPython()"> Run python </a></p>
  <p><a id="table-data"> See the table </a></p>

  <script src="/socket.io/socket.io.js"></script>
  <script>
    var msg = {
      msg: "TestMsgSend",
      iParam: 100,
      sParam: "Test Param 1",
      aParam: [1, 2, 3]
    }
    var socket = io();

    socket.on("server:finished", function (msg) {
      // msg = "TestMsgReceived", for further usage
      console.log("\nId: " + socket.id + "\nmsg: " + msg.msg + "\niParam: " + msg.iParam + "\nsParam: " + msg.sParam + "\naParam: " + msg.aParam);

      document.getElementById("table-data").setAttribute("href", "/data");
    });

    function runPython() {
      socket.emit("client:run", msg);
    }
  </script>
</body>
</html>

<强> app.js

var express = require("express");
var app = express();
var http = require("http").Server(app);
var io = require("socket.io")(http);

app.use("/", express.static(__dirname + "/"));

// ***************************************************************************
// ***************************************************************************
// ***** Your code
// ***************************************************************************
// ***************************************************************************

io.on("connection", function (socket) {
  console.log("New connection with id: " + socket.id);

  socket.on("client:run", function (msg) {
    // msg = "TestMsgSend", for further usage
    console.log("\nId: " + socket.id + "\nmsg: " + msg.msg + "\niParam: " + msg.iParam + "\nsParam: " + msg.sParam + "\naParam: " + msg.aParam);

    // ***************************************************************************
    // ***************************************************************************
    // ***** Your code
    // ***************************************************************************
    // ***************************************************************************

    msg.msg = "TestMsgReceived";
    msg.iParam++;
    msg.sParam = "Test Param 2";
    msg.aParam.push(4, 5, 6)
    io.emit("server:finished", msg);
  });
});

// ***************************************************************************
// ***************************************************************************
// ***** Your code
// ***************************************************************************
// ***************************************************************************

http.listen(80, function () {
  console.log("listening on *:80");
});

<强>的package.json

{
  "name": "test",
  "version": "1.0.0",
  "description": "",
  "main": "app.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.16.2",
    "socket.io": "^2.0.4"
  }
}

节点app.js 开始,然后享受

答案 4 :(得分:-1)

为什么不像一个简单的保护变量?在您的代码中:

var ready = false; // 1) the guard

app.get('/data', function(req, res) {
    if (ready) { // 2) view execution blocked until guard is ready
        res.render(__dirname + '/well.html');
    }
});

app.get("/run", function(req, res) {
    var pyshell = new PythonShell('script2.py');
    pyshell.send(JSON.stringify(thelist))
    pyshell.on('message', function (message) {
        // received a message sent from the Python script (a simple "print" statement)
        jsondata += message
    });

    // end the input stream and allow the process to exit
    pyshell.end(function (err) {
        if (err) {
            throw err;
        };
        ready = true; // 3) if evetything is OK the guard is now ready
        console.log('finished');
    });
    res.redirect('/')
    thelist = []
});