JavaScript >> Javascript 文檔 >  >> Node.js

使用 Node.js 製作圖片投票遊戲(第 2 部分)

在本教程的第一部分,我們奠定了我們的 node.js Web 應用程序的基礎。您了解了運行和安裝節點、npm 和 nedb 庫,我們甚至編寫了第一個模塊。本週我們將繼續我們的圖片投票應用的路線和視圖。

路由和配置文件

上週我們製作了一個模塊來處理兩個數據集的初始化 - users照片 .這些數據集由模塊導出,這允許我們在其他 js 文件中要求並訪問它們。我們將在我們的 routes.js 中執行此操作 文件,其中包含應用程序將響應的所有路由。

routes.js

/**
 * This file defines the routes used in your application
 * It requires the database module that we wrote previously.
 */ 

var db = require('./database'),
    photos = db.photos,
    users = db.users;

module.exports = function(app){

    // Homepage
    app.get('/', function(req, res){

        // Find all photos
        photos.find({}, function(err, all_photos){

            // Find the current user
            users.find({ip: req.ip}, function(err, u){

                var voted_on = [];

                if(u.length == 1){
                    voted_on = u[0].votes;
                }

                // Find which photos the user hasn't still voted on

                var not_voted_on = all_photos.filter(function(photo){
                    return voted_on.indexOf(photo._id) == -1;
                });

                var image_to_show = null;

                if(not_voted_on.length > 0){
                    // Choose a random image from the array
                    image_to_show = not_voted_on[Math.floor(Math.random()*not_voted_on.length)];
                }

                res.render('home', { photo: image_to_show });

            });

        });

    });

    app.get('/standings', function(req, res){

        photos.find({}, function(err, all_photos){

            // Sort the photos 

            all_photos.sort(function(p1, p2){
                return (p2.likes - p2.dislikes) - (p1.likes - p1.dislikes);
            });

            // Render the standings template and pass the photos
            res.render('standings', { standings: all_photos });

        });

    });

    // This is executed before the next two post requests
    app.post('*', function(req, res, next){

        // Register the user in the database by ip address

        users.insert({
            ip: req.ip,
            votes: []
        }, function(){
            // Continue with the other routes
            next();
        });

    });

    app.post('/notcute', vote);
    app.post('/cute', vote);

    function vote(req, res){

        // Which field to increment, depending on the path

        var what = {
            '/notcute': {dislikes:1},
            '/cute': {likes:1}
        };

        // Find the photo, increment the vote counter and mark that the user has voted on it.

        photos.find({ name: req.body.photo }, function(err, found){

            if(found.length == 1){

                photos.update(found[0], {$inc : what[req.path]});

                users.update({ip: req.ip}, { $addToSet: { votes: found[0]._id}}, function(){
                    res.redirect('../');
                });

            }
            else{
                res.redirect('../');
            }

        });
    }
};

這裡app 是我們將在 index.js 中創建的 Express.js Web 應用程序的一個實例 文件。我們正在導出一個將應用程序作為參數的函數,這允許我們稍後將其作為依賴項注入。

我們將編寫的下一個文件是為我們的應用程序設置一些設置的配置文件:

config.js

/**
 * This file runs some configuration settings on your express application.
 */ 

// Include the handlebars templating library
var handlebars = require('express3-handlebars'),
    express = require('express');

// Require()-ing this module will return a function
// that the index.js file will use to configure the
// express application

module.exports = function(app){

    // Register and configure the handlebars templating engine
    app.engine('html', handlebars({ 
        defaultLayout: 'main',
        extname: ".html",
        layoutsDir: __dirname + '/views/layouts'
    }));

    // Set .html as the default template extension 
    app.set('view engine', 'html');

    // Tell express where it can find the templates
    app.set('views', __dirname + '/views');

    // Make the files in the public folder available to the world
    app.use(express.static(__dirname + '/public'));

    // Parse POST request data. It will be available in the req.body object
    app.use(express.urlencoded());

};

我們正在為我們的視圖使用把手模板引擎(在這個適配器庫的幫助下),因為它很容易編寫並且支持佈局視圖。佈局將允許我們為所有頁面共享一個通用設計,這可以節省大量時間。上面的代碼還使用靜態連接中間件來提供 /public 中的文件 文件夾。這是讓所有網站資產都可以通過網絡瀏覽器訪問的最佳方式。

下一個文件是 index.js ,它將所有這些模塊聯繫在一起,並為我們初始化一個新的 Express.js 應用程序:

index.js

/**
 * This is the main file of the application. Run it with the
 * `node index.js` command from your terminal
 *
 * Remember to run `npm install` in the project folder, so 
 * all the required libraries are downloaded and installed.
 */ 

var express = require('express');

// Create a new express.js web app:

var app = express();

// Configure express with the settings found in
// our config.js file

require('./config')(app);

// Add the routes that the app will react to,
// as defined in our routes.js file

require('./routes')(app);

// This file has been called directly with 
// `node index.js`. Start the server!

app.listen(8080);
console.log('Your application is running on http://localhost:8080');

偉大的!我們的應用程序正在成型!要啟動它,請執行命令 node index.js ,並且服務器將開始監聽 port 8080 .但是,如果您嘗試在瀏覽器中打開 http://localhost:8080,此時您只會看到缺少模板文件的錯誤消息。這是因為我們還沒有寫出我們的觀點。

觀點

我們將創建的第一個視圖是佈局。該文件將定義我們網站其他頁面共享的通用 HTML。您的應用可能有多個佈局(例如,如果您希望為主頁和管理屏幕分別設計),但我們這裡只有一種。

視圖/佈局/main.html

<!DOCTYPE html>
<html>

    <head>
        <meta charset="utf-8"/>
        <title>Node.js Picture Voting Game</title>

        <meta name="viewport" content="width=device-width, initial-scale=1" />

        <link href="http://fonts.googleapis.com/css?family=Open+Sans:300,700" rel="stylesheet" />
        <link href="css/styles.css" rel="stylesheet" />

    </head>

    <body>

        <header>
            <h1><span class="green">Cute</span> or <span class="red">NOT?</span></h1>
            <h2>A Node.js Voting Game</h2>
        </header>

        {{{body}}}

        <footer>
            <a class="tz" href="https://tutorialzine.com/2014/01/nodejs-picture-voting-game-part-1/">Tutorial: Node.js Picture Voting Game</a>

    </body>
</html>

{{{body}}} 標籤會自動替換為使用此佈局的其他視圖的 HTML。這是特定於索引頁面的 HTML:

views/home.html

<nav>
    <a class="active" href="./">Game</a>
    <a href="./standings">Standings</a>
</nav>

{{#if photo}}

    <img src="photos/{{photo.name}}" width="530" height="420" alt="Cat Picture" />

    <div class="button-holder">
        <form action="./cute" method="post">
            <input type="hidden" name="photo" value="{{photo.name}}" />
            <input type="submit" value="Cute!" />
        </form>
        <form action="./notcute" method="post">
            <input type="hidden" name="photo" value="{{photo.name}}" />
            <input type="submit" value="Not Cute!" />
        </form>
    </div>

{{else}}

    <h3>No more photos to vote on! Check out the <a href="./standings">standings</a>.</h3>

{{/if}}

Handlebars 模板可以具有 if/else 結構、循環和許多其他功能,可讓您編寫乾淨的 HTML。這是排名頁面的模板:

views/standings.html

<nav>
    <a href="./">Game</a>
    <a class="active" href="./standings">Standings</a>
</nav>

{{#if standings}}

    <ul>

        {{#each standings}}

        <li>
            <img src="photos/{{name}}" alt="Cat picture thumbnail" />
            <p class="up">{{this.likes}}</p>
            <p class="down">{{this.dislikes}}</p>
        </li>

        {{/each}}

    </ul>

{{/if}}

通過使用模板,我們能夠將用於呈現數據的代碼與數據本身分開。您可以在 express Web 應用程序中使用許多不同的模板引擎。

我們完成了!

至此,我們的 Node.js 圖片投票遊戲就完成了!您可以使用無數 node.js 模塊和庫中的一些來增強它,並以您希望的任何方式對其進行修改。我希望您發現本教程對您有用!如果您有任何建議,請將它們帶到下面的評論部分。


Tutorial JavaScript 教程
  1. 正則表達式匹配括號

  2. 最後!我建立了我的投資組合

  3. React 三纖維著色器的研究

  4. 與電容器的離子深度鏈接/通用鏈接。

  5. 非 Redux 全局狀態庫的四種不同方法

  6. JavaScript 字母數組 |簡單的示例代碼

  7. 在 AWS Amplify 上部署您的 React.js 應用程序

  1. 如何使用 Node 和 Google Puppeteer 生成 HTML 表格和 PDF

  2. 使用 Pokémon 和 React 理解狀態的概念!

  3. 創建 javascript 類時使用什麼模式?

  4. 在 VSCode 中調試 Nodejs

  5. 為 iOS 修復 React Native WebView 的 postMessage

  6. 為 Bootstrap 5 開發免費的低代碼儀表板生成器

  7. React 中的漣漪效應

  1. 如何使用 Firebase 處理 Node JS 上的身份驗證🔥

  2. JavaScript-30-Day-6

  3. JavaScript 中的 Cargo-Culting

  4. Ruby on Rails 與 Node.js:正面對比