NodeJSMongoDB Database for Front-End Notes & Mongoose & Self-Made Interface & MVC Architecture Thought | Practice

Keywords: Javascript Database MongoDB Mongoose JSON

MongoDB database

1.1 Introduction to NoSQL

With the rise of Internet web2.0 website, traditional SQL database (relational database) has been unable to cope with web2.0 website, especially the super-large-scale and highly concurrent SNS (social network system, Renren) type web2.0 pure dynamic website, which has exposed many problems that are difficult to overcome, while the non-relational database has been very strong because of its own characteristics. Rapid development. NoSQL database is created to solve the challenges brought by multiple data types in large-scale data aggregation, especially the big data application problems.

 

Traditional databases MySQL, SQL Server, Oracle and Access are all SQL structured databases.

The characteristic of these structured databases is that "table" has a clear concept of "field (column)", and the field is fixed. If you want to add fields, all existing entries need to be changed.

The advantage of SQL is that the query can be very complex, such as searching all "girls whose Chinese scores are higher than math scores and whose English scores are in the top three of the class".

But now, you will find that many times retrieval can be very simple, not so complicated. For example, the telephone fee is detailed and there is no need to retrieve: the call lasts more than 5 minutes and is actively dialed at night.

 

Disadvantage of structured databases: If fields need to be added in the future, all previous entries should be added together. For example, you have 20,000 entries. If you suddenly need to add a Chinese score field, then 20,000 existing entries need to change the field, which is particularly time-consuming. That is to say, flexibility is not enough!

The advantages of structured database: fast search, the concept of primary key, slave key, master-slave search, mapping and other advanced database concepts.

 

In this age of SQL, the advantages have been reduced and the disadvantages have been magnified.

NoSQL database is very suitable if you only need to save and do not need to search precisely.

 

China Unicom's online records, everyone will have a pile of data, this data is: as long as you save, basically do not need to find. And often the structure changes.

 

So MySQL and other structured data, their advantages (fast search, master-slave search advanced functions) we are more and more unused, shortcomings (the structure is difficult to change) we need more and more. So people began to reflect on the SQL database.

So it's called NoSQL, a non-relational database. Data does not have the concept of rows and columns. It uses k-v to store children or JSON. Advantages and disadvantages happen to be reversed by SQL type, which is suitable for structural changes and not suitable for precise search. Just adapted to the era of "as long as storage, not search".

NoSQL has a nickname called Not Only SQL, not just database. Actually, it's a joke. It's much weaker than SQL.

 

This paper introduces two most commonly used databases in work: MongoDB (Document Database) and Redis(K-V Pair Database). They are NoSQL.

Document-based databases (such as MongoDB) have the advantages of less stringent data structure, variable table structure, and no need to pre-define table structure like relational databases.

 

Non-relational databases are now widely used: social platforms, APP communication records, bank pipelining, telecommunications call details and so on. Any usage scenario that only needs to be saved but does not need to be finded accurately can be used with a non-relational database.

NoSQL is a non-relational database, and the fields of each entry are not fixed. Take MongoDB as an example:

{"name":"Xiao Ming","age":12,"sex":"male"}
{"name":"Xiaohong","age":13,"sex":"female"}
{"name":"Xiaogang","age":14,"sex":"male", "chengji":99}
{"name":"Small black","age":14,"sex":"male", "gongzi":5000}

1.2 MongoDB database installation

In order to simulate a project and, more importantly, let you understand the interaction mode between the front end and the back end, we must learn the database and have the whole stack thinking.

 

MongoDB is a NoSQL (No Only SQL, non-relational database) database.

MongoDB is not software, but a bunch of CLI s.

 

MongoDB is green, which means that decompression is available without installation.

Official website: https://www.mongodb.com/

Download address: https://www.mongodb.com/download-center

 

Unzip to your computer disc character (do not appear in Chinese): C: Program Files

 

After decompression, the painting style is as follows:

The exe files provided in the bin folder, instead of double-clicking, should be run in cmd. They are CLI programs:

 

 

Setting this bin folder as an environment variable of the system ensures that CMD can run them under any disk symbol.

 

 

Right-click Properties on Computer

 

 

Change environment variables as shown

 

 

Copy in the path of the bin folder.

 

 

Open CMD and enter it under any disk symbol

mongo -version

You can view the version.

 

If the environment variable is not set correctly, an error will be reported.

 

The use of the database requires you to install a windows patch: KB2731284.

If the patch is not installed, check the method:

 https://jingyan.baidu.com/article/fd8044fa3c47e15031137acd.html

1.3 Start-up of Database

Create a folder called database on the c disk and open the cmd input:

mongod --dbpath c:\database

The mongod Express startup command opens the data library, --dbpath indicates the location of a database to be selected.

 

 

Do not close this CMD, the database will be closed when it is closed. At this time, open a new CMD window to do other operations:

mongo

Enter the REPL environment of MongoDB

 

1.4 Use of database

Start up first, then build a new CMD warehouse, use the mongo command to manage the data, and enter the mongo return in cmd.

Let's try to see that in mongo's REPL environment is > rather than C: Users admin > C MD environment:

Create (switch) databases:

use student

 

Insert data:

db.banji0902.insert({"name":"Xiao Ming", "age":12})

 

Query all:

db.banji0902.find()

 

Accurate query:

db.banji0902.find({"name":"Xiao Ming"})

1.5 MongoDB hierarchy

From big to small in MongoDB: Database > collections > Documents > records

Come from: https://docs.mongodb.com/manual/introduction/

3.5.1 records entry and documents document

record (entry)

Recording in MongoDB is a file, which is a data structure consisting of field and value pairs. MongoDB documents are similar to JSON objects. Field values can include other documents, arrays, and document arrays.

 

A document in documents is also called a record entry. The entry is similar to JSON structure and is a k-v pair. The value can be other objects, arrays, and arrays of objects.

1.5.2 collections set (table)

MongoDB uses collections collections to store documents, which are equivalent to "tables" in SQL. But unlike tables, collections do not require documents to have the same schema.

 

Below is a collection of four documents with three entries (name, age, sex)

{"name":"Xiao Ming","age":12,"sex":"male"}
{"name":"Xiaohong","age":14,"sex":"female"}
{"name":"Small black","age":14,"sex":"male"}
{"name":"Small basket","age":13,"sex":"male"}

Documents are stored in collections (tables), and collections are stored in databases.

1.5.3 database

There can be many collections (tables) in the database.

1.6 Common CMD commands

The control of mongodb generally uses CMD commands, but there are also visual database software.

 

There are two kinds of orders:

CMD command

REPL command (you can enter this environment with mongo and enter it at the small pointer ">" prompt)

 

First learn what commands can be run in CMD?

mongod means boot, mongo means REPL environment entering database, mongo import import import data and mongo export export export data.

 

Start up first, and all future operations must start up first:

mongod --dbpath c:\database

First of all, to prepare external data and write several documents, it must be a. txt file, not a. json file.

 

Import data, create a new CMD window, enter:

Mongoimport-d student-c banji0902. / simulated data. txt

 

Delete old data and import new data

Mongoimport-d student-c banji0902. / analog data. txt--drop

 

Export data in specified databases and collections (tables):

mongoexport -d student -c banji0902 -o c:\haha.txt
- d represents the specified database
 - c denotes the specified table name
 - o denotes the export path
 -- drop represents data before emptying

1.7 Common REPL commands

After booting, another CMD window, input mongo and press Enter to the REPL environment of the database, and then operate the database.

 

Switch (create) a database:

use student

 

Query which databases are currently available:

show dbs

 

See which collections (tables) are in the current database

show collections

 

Delete the database:

db.dropDatabase()

 

Insert data into the table:

db.banji0902.insert({"name":"Xiao Ming", "age":12})

 

All data in the query table:

db.banji0902.find()

 

Accurate query:

db.banji0902.find({"name":"Xiao Ming"})

 

And look up: look up age is 18, and male

db.banji0902.find({"sex":"male", "age":18})

 

Or ($or) Search: Search for an 18-year-old or "male"

db.banji0902.find({$or:[{"sex":"male"}, {"age":38}]})

 

Greater than ($gt):

db.banji0902.find({"age":{$gt:18}})

 

Greater than or equal to ($gte), less than ($lt), less than or equal to ($lte)

 

 

Look for boys, aged between 18 and 25:

db.banji0902.find({"sex":"male", "age":{$gte:18, $lte:25}})

 

Regular expressions can be used in queries:

db.banji0902.find({"name":/Small/g})

 

Query people who like to fight against landlords:

db.banji0902.find({"hobby":"Fight against landlords"})

 

Modify ($set):

db.banji0902.update({"name":"Small 1"}, {$set:{"sex":"Manly woman"}})

 

Delete a data:

db.banji0902.remove({"name":"Small 1"})

1.8 MongoDB and Nodejs Connections

Official API: http://mongodb.github.io/node-mongodb-native/2.2/

Add, delete and change check (CRUD) operation: http://mongodb.github.io/node-mongodb-native/2.2/tutorials/crud/

Install the dependencies of mongodb, and install the specified version number. Do not install the latest version:

npm install mongodb@2.2.28 --save

Note: The API of the mongodb version is different, so it depends on the official documents:

 http://mongodb.github.io/node-mongodb-native/3.0/

 

var MongoClient = require("mongodb").MongoClient; //Leading bag

//Database Address
var dbUrl = 'mongodb://127.0.0.1:27017/student';
//Connect to the database
MongoClient.connect(dbUrl, function(err,db){
    if(err){
        console.log("Failure of database connection");
        return;
    }

    console.log("Successful database connection!");
    db.close();
})

 

Query data:

var MongoClient = require("mongodb").MongoClient; //Leading bag

//Database Address
var dbUrl = 'mongodb://127.0.0.1:27017/student';
//Connect to the database
MongoClient.connect(dbUrl, function(err,db){
    if(err){
        console.log("Failure of database connection");
        return;
    }

    console.log("Successful database connection!");

    //Query the current database banji0902 Table data
    db.collection("banji0902").find({"age":{$gt:18}}).toArray(function(err,data){
        console.log(data);
        db.close();
    })
})

Traditional connection restrictions are generally not used because:

l. The callback function is ugly.

l. Inconvenient MVC programming

l. Complexity of native API s

Mongoose database

2.1 Additional data

Official website: https://mongoosejs.com/

node.js'elegant mongodb object modeling.

Installation Dependency:

npm install --save mongoose@4

 

Write a Hello World. Routine: Introducing packages, creating schema s, creating models, instantiating models, calling save() methods.

var mongoose = require("mongoose"); //Leading bag

//Connect to the database. The database is called iqd,If the database does not exist, it will be created automatically
mongoose.connect("mongodb://127.0.0.1:27017/iqd", {useMongoClient:true});

//Create a database structure( Schema)
var studentSchema = {
    name:String,
    age:Number,
    sex:String
}

//Create the model (returns a class),student Is the name of the table (collection)
//Attention: in nodejs The surface created in the“ student",But it will be automatically added to the database. s,Become " students"
var Student = mongoose.model('student', studentSchema);

//new An example
var xiaoming = new Student({"name":"Xiao Ming","age":12,"sex":"male"});

//Save data
xiaoming.save();

 

Run node app.js

iqd data is automatically created and a table called student is created (the database automatically adds s s), so it becomes student s

 

Start-up, REPL and console each have a CMD.

 

mongoose is such a philosophy that developers can not feel that they are manipulating data. They can manage databases only by using new save and other classes and instances. Besides new and svae(), they can create data, and they can also create databases by Student.insert({}).

2.2 search

//Method of querying database 1:
Student.find({"age":{$gt:18}}, function(err,data){
    console.log(data)
})

//Method of querying database 2:
Student.find({"age":{$gt:18}}).exec(function(err,data){
    console.log(data)
})
lookup

2.3 delete

Delete method is very flexible, you can call Student's remote method with class dotting

//Method 1 for deletion
Student.remove({"name":"Small black"}, function(err,data){
    console.log(data)
})

//Method 2 for deletion:
Student.remove({"name":"Small black"}).exec(function(err,data){
    console.log(data)
})
Class management

 

You can also call the remove() method of the instance to delete

Student.find({"name":"Small 6"}, function(err,data){
    var xiao6 = data[0];
    xiao6.remove(); //delete
})
Call instance

2.4 amendment

Student.find({"name":"Small 3"}, function(err,data){
    var xiao3 = data[0];
    xiao3.sex = "Manly woman"; //Assignment modification
    xiao3.save();
})
mongoose modification

 

If you don't use mongoose, use native

db.collections("students").update({"name":"Small 3"}, {$set:{"sex":"Manly woman"}})

2.5 Packaging Static Method

I just found that many methods can be called with class names (constructors) dotted

Student.find()
Student.remove()

So how do you encapsulate some methods by yourself? And it can be called by class dotting. mongoose provides a method (static method) to customize the encapsulated class. The steps are as follows:

l When creating a schema, you must create it with new mongoose.Schema()

l. Binding static methods with statics. *** on an example of schema

var mongoose = require('mongoose'); //Leading bag
//Connect to the database. The database is called iqd,If the database does not exist, it will be created automatically
mongoose.connect('mongodb://localhost/iqd',{useMongoClient:true});

//Create a database structure(Schema)
var studentSchema = new mongoose.Schema({
    name: String,
    age : Number,
    sex : String
})

//Encapsulating custom static methods
studentSchema.statics.check = function(name,callback){
    //this Express Student class
    this.find({"name":name}, function(err,data){
        var exsit = data.length > 0;
        //Pass the result through the parameter to the callback function
        callback(exsit)
    })
}

var Student = mongoose.model('student', studentSchema);

//Verify someone Does it exist?
Student.check("Xiao Ming", function(exsit){
    console.log(exsit)
})

2.6 Packaging Dynamic Method

Instance dotting calls are called dynamic methods:

var mongoose = require('mongoose'); //Leading bag
//Connect to the database. The database is called iqd,If the database does not exist, it will be created automatically
mongoose.connect('mongodb://localhost/iqd',{useMongoClient:true});

//Create a database structure(Schema)
var studentSchema = new mongoose.Schema({
    name: String,
    age : Number,
sex : String,
})

//A Dynamic Method for Encapsulating Customization
studentSchema.methods.bianxing = function(name,callback){
    //this represents an instance
    this.sex = this.sex == "male" ? "female" : "male";
}

var Student = mongoose.model('student', studentSchema);

//Using dynamic methods
Student.find({"name":"Xiao Ming"}, function(err,data){
    var ren = data[0]; //Example
    ren.bianxing();
    ren.save();
    console.log(data)
})

Nodejs + MongoDB technology stack is seldom used in work, because there are backstage brothers and sisters, learning Nodejs, MongoDB HTTP server development purposes:

Understand how the front-end and back-end work, cooperate, how to transfer data, and what is the situation of adding, deleting and modifying the database.

To write a JSON interface, call the front end

 

3. Making a set of interfaces for additions, deletions and alterations

Do a RESTful-style routing interface and create simulated data:

{"id":1001,"name":"Xiao Ming","age":12,"sex":"male","job":"Front end"}
{"id":1002,"name":"Xiaohong","age":15,"sex":"female","job":"Design"}
{"id":1003,"name":"Xiaogang","age":12,"sex":"male","job":"Teacher"}
{"id":1004,"name":"Cockroach","age":13,"sex":"male","job":"back-end"}
{"id":1005,"name":"Little green","age":18,"sex":"male","job":"Teacher"}
{"id":1006,"name":"indigo plant","age":18,"sex":"female","job":"Front end"}
{"id":1007,"name":"Small black","age":18,"sex":"female","job":"product"}
{"id":1008,"name":"Floret","age":18,"sex":"female","job":"Design"}

They are all users, so when importing into the database, in a table named users, note that the last letter of the table name must be s.

Create the models folder, create User.js in the folder, and create the data structure

var mongoose = require('mongoose'); //Leading bag
//Default exposure
module.exports = mongoose.model('user', {
    id:Number,
    name: String,
    age : Number,
    sex : String,
    job : String
});
data structure

 

app.js query interface

var mongoose = require('mongoose'); //Leading bag
var User = require('./models/User.js');
var express = require('express'); //Leading bag
var app = express();

//Connect to the database. The database is called gziqd,If the database does not exist, it will be created automatically
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/gziqd',{useMongoClient:true});

//Query all users of the database
app.get("/users", function(req,res){
    User.find().exec(function(err,data){
        res.json({"data": data})
    })
});

//Query one id Users
app.get("/users/:id", function(req,res){
    var id = req.params.id;
    //Appoint id query
    User.find({"id": id}).exec(function(err,data){
        res.json(data[0])
    })
});

app.listen(3000)

 

 

Issue POST requests to create data

index.html front-end page:

<html>
<head>
    <title>Document</title>
</head>
<body>
    <!-- increase -->
    <p>ID : <input type="text" id="idTxt" /></p>
    <p>Full name:<input type="text" id="name" /></p>
    <p>Work:<input type="text" id="job" /></p>
    <button id="btn1">Create user</button>
    <hr>

    <!-- delete -->
    <p>
        Deleted person's id : <input type="text" id="delId"/>
        <button id="btn2">delete</button>
    </p>
    <hr>

    <!-- modify -->
    <p>
        Renamed id : <input type="text" id="changeId"/><br>
        Why should we change the name?<input type="text" id="changeToName"/>
        <button id="btn3">modify</button>
    </p>
    <hr>

    <!-- query -->
    <p>
        query id : <input type="text" id="checkId"/>
        <button id="btn4">query</button>
    </p>
</body>
<script type="text/javascript" src="js/jquery-2.2.4.min.js"></script>
<script type="text/javascript">
     //Issue POST Request, create user, submit to database (server)
     $("#btn1").click(function(){
        $.post("/users",{
            id : $("#idTxt").val(),
            name: $("#name").val(),
            job : $("#job").val()
        }, function(data){
            if(data == "ok"){
                alert("Create success!");
            }
        })
     });
</script>
</html>

 

Back-end intercepts requests for post s to add data and inserts data into the database

app.post("/users", function(req,res){
    var form = new formidable.IncomingForm();
    form.parse(req, function(err, data){
        //Method of inserting data: User.create()
        User.create(data, function(){
            res.send("ok")
        })
    });
});

 

Issue delete delete request:

There are 26 types of requests. Next, delete requests and patch requests are used.

$("#btn2").click(function(){
    $.ajax({
        url : "/users/" + $("#delId").val(), //Deleted id
        type : "delete",
        success: function(data){
             if(data == "ok"){
                 alert("Success");
            }
        }
    });
});

 

The back end intercepts delete requests to delete data and deletes the user with the specified id in the database

app.delete("/users/:id", function (req, res){
    var id = req.params.id;
    //The syntax for deleting data: User.remove();
    User.remove({ "id": id } , function (err, data){
        res.send("ok");
    });
});

 

Send a patch modification request:

$("#btn3").click(function(){
    $.ajax({
        url : "/users/" + $("#changeId").val() ,
        type : "patch",
        data : {
            "name": $("#changeToName").val()
        },
        success : function(data){
            if(data == "ok"){
                    alert("Success");
            }
        }
    });
});

 

Backend intercepts patch requests to modify data and modifies users with specified IDS in the database

app.patch("/users/:id", function (req, res) {
    var id = req.params.id; 
    var form = new formidable.IncomingForm();
    form.parse(req, function (err, jsonobj) {
        var name = jsonobj.name; //From the front end name
        User.update({"id": id }, {"$set": {"name":name} }, function (err, results) {
            res.send("ok");
        });
    });
});

 

Complete app.js implements many interfaces.

The following red code is express's route, the green code is formidable to get the data, and the blue code is about the database.

var formidable = require('formidable');
var mongoose = require('mongoose');
var User = require('./models/Users.js'); //Introducing data structure
var express = require('express');
var app = express();

//Static state www Folder
app.use(express.static("www"));

//Connect to a database called gziqd. If the database does not exist, it will be created automatically.
mongoose.Promise = global.Promise;
mongoose.connect('mongodb://localhost/gziqd', {useMongoClient:true});

//Query all users of the database
app.get("/users" ,function(req,res){
    User.find().exec(function(err, data){
        res.json({"data" : data})
    })
});

//Query one id Users
app.get("/users/:id" ,function(req,res){
    var id = req.params.id;
    // Appoint id query
    User.find({"id" : id}).exec(function(err, data){
        res.json(data[0])
    })
});

// Backend receives requests, inserts data, and creates users
app.post("/users" ,function(req,res){
    var form = new formidable.IncomingForm();
    form.parse(req, function(err, data){
       //Syntax for inserting data: User.create();
       User.create(data, function(){
            res.send("ok");
       })
    });
});

//Delete request
app.delete("/users/:id" ,function(req,res){
    var id = req.params.id;
    //The syntax for deleting data: User.remove();
    User.remove({"id":id}, function(){
        res.send("ok");
    })
});

//Modification request
app.patch("/users/:id" ,function(req,res){
    var id = req.params.id;
    var form = new formidable.IncomingForm();
    form.parse(req, function(err, data){
       var name = data.name; //Submitted by the front end name data
       //Modify the grammar of the data: User.update();
       User.update({"id" : id}, {$set:{"name":name}}, function(err, data){
            res.send("ok");
       })
    });
});

app.listen(3000);

RESTful-style routing:

 

function

URL

Request type

increase

http://127.0.0.1/users

POST request

delete

http://127.0.0.1/users/1001

DELETE request

modify

http://127.0.0.1/users/1001

PATCH request

query

http://127.0.0.1/users

http://127.0.0.1/users/1001

GET request

 

 

A URL address can do multiple tasks, distinguished by the type of HTTP request.

 

RESTful is an abbreviation of English words, a semantically beautiful form of URL routing.

 

 

 

Before the RESTful epidemic in 2015, the route is as follows:

 

 

function

URL

Request type

increase

http://127.0.0.1/adduser.php

POST request

delete

http://127.0.0.1/deluser.php?id=1001

GET request

modify

Http://127.0.0.1/changeuser.php?Id=1001&name=new name

GET request

query

http://127.0.0.1/users.php

http://127.0.0.1/users.php?id=1001

GET request

 

 

Disadvantages:

 

Different php files are used in each business, which is not convenient for MVC programming.

 

(2) Exposing technical details, people can easily know how you handle pages and transfer parameters.

 

Summarize the writing of mongoose:

 

function

Writing method

increase

User.create({})

delete

User.remove({"id" : id})

modify

User. update ({"id": id}, {"$set": {"name": new name from the front end})

lookup

User.find()

User.find({"id":id})

IV. Architectural Ideas of MVC

4.1 MVC theoretical knowledge

Models model

 

 

Views view

 

 

Controllers controller (contractor)

 

 

 

Model (model) is the part of an application that is used to process application data logic.

Usually the model object is responsible for accessing data and computing in the database. The dirtiest and tightest work is done by models.

In M VC, M represents a pluggable, self-debuggable single logic unit, model.

 

The content of the model layer is only responsible for its own functions, not for the business logic of the whole project. It can unit test itself.

 

View is the part of an application that processes data display.

Usually views are created based on model data.

 

Controller is the part of an application that deals with user interaction.

Usually the controller is responsible for reading data from the view, controlling user input and sending command requests to the model. Once you get the data from the model, render the view.

 

 

Controllers send requests to multiple models, request their data, and submit them to the view for presentation.

MVC layering also simplifies group development. Different developers can develop views, controller logic and business logic at the same time.

 

4.2 MVC Small Project - Project Introduction

Make a factor calculator with machine learning ability.

Logic of the project:

 

When the query button is clicked on the front page, the front-end js calls window.location to jump the page to / cha/9954 routing page:

 

Nodejs is not good at computing, so let's consider one thing: machine learning.

Store the number queried by the user, such as 9954 query by the user, and then create 9954.txt file in the data folder. This is where the factor array is stored. When other users query 9954, they do not need to calculate, but directly submit the results! In this way, the more people you use, the more answers the machine knows, and thus faster and faster. Because Nodejs finds a file much faster than calculating what, I/O operations are Nodejs'strong points.

 

Logic:

 

4.3 MVC Small Project-Model Layer Writing

Create a model car folder and create two new files:

match.js provides functions for calculating factors

file.js provides the operation function of the file (read the file array, write the array to the file, determine whether the file exists)

 

That is to say, "Model layer employees" have two functions: file operation function and mathematical calculation function.

 

The model layer is only responsible for its own functions and does not need to see the global business.

Create a data folder to store all computed answers:

 

The fs.stat() function checks whether a file exists, returns JSON and undefined.

fs.stat(path, callback)

In the file.js file, an isExist() function is encapsulated, which receives numbers and callbacks and returns true/false through the callback function.

Represents whether the file exists or not, and the true/false return value ultimately needs to be provided to the controller for use.

 

var fs = require("fs");
//Judging whether a file exists or not, receiving a digital parameter, such as 886, can determine 886..txt Does it exist?
function isExist(n,callback){
    //Asynchronous functions are not allowed return,So only callback function transfer parameters can be provided.
    fs.stat("./data/"+ n +".txt",function(err,stats){
        //File exists stats Will return json,No return undefined
        var result = stats === undefined ? false : true;
        callback(result);
    });
};

//Unit test, check 886.txt Does it exist?
isExist(886,function(result){
    console.log(result);
});
//Exposure function
exports.isExist = isExist;

 

Write a function, unit test a function.

var fs = require("fs");
//Judging whether a file exists or not, receiving a digital parameter, such as 886, can determine 886..txt Does it exist?
function isExist(n, callback){
   ...
}
//Outward exposure
exports.isExist = isExist;

// Unit testing. Check 886.txt Is there any
// isExist(886,function(result){
//     console.log(result)
// });


//Write an array to a file
function writeArray(n, arr, callback){
    fs.writeFile("./data/"+ n +".txt", JSON.stringify(arr), function(err){
        if(err){
            callback(false)
        }else{
            callback(true)
        }
    })
}
//Outward exposure
exports.writeArray = writeArray;

// Unit test, write data
// writeArray(8888,[2,2,2],function(result){
//     console.log(result)
// });

//Read an array in a file
function readArray(n, callback){
    fs.readFile("./data/" + n + ".txt", function(err,data){
        if(err){
            //If the file does not exist
            callback(false)
        }else{
            //If the file exists, the read array result is returned
            var arr = JSON.parse(data)
            callback(arr)
        }
    })
}

//unit testing
// readArray(888, function(arr){
//    console.log(arr)
// })
//Outward exposure
exports.readArray = readArray;

math.js Module, which provides a function:
//Calculate the factor function and return an array
function calcFactor(n){
    var arr = [];
    for (var i = 1; i <= n; i++) {
        if(n % i == 0){
            arr.push(i)
};
    }
    return arr;
}
console.log(calcFactor(48));
exports.calcFactor = calcFactor;

4.4 MVC Small Projects - Controller and View Layer

Controller is the middleware. We put the routing callback function in the external js file separately, which is the controller. When the project is big, it can be divided into many parts.

var express = require("express");
var app = express();
var mainCtrl = require("./controllers/mainCtrl.js");

//Setting up Template Engine
app.set("view engine", "ejs");

//Routing list, putting the callback function of Middleware in the external file
app.get("/", mainCtrl.showIndex); //Display home page
// app.get("cha/:num", mainCtrl.showCha); //Pages showing results

app.listen(3000);

 

Exposure middleware:

exports.showIndex = function(req,res){
    res.render("index.ejs")
}

exports.showCha = function(req,res){

}

 

index.html view

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style type="text/css">
        body{background: #ccc;}
        .wrap{
            background: #fff;
            width: 900px;height: 400px;
            border-radius:10px;
            padding:10px;margin:20px auto;
            text-align:center;
        }
        input{
            width: 60%;font-size:22px;border-radius:5px;
            border:1px solid #eee;padding:0 5px;
        }
        button{width: 60px;height: 30px;background: skyblue;border:none;}
    </style>
</head>
<body>
    <div class="wrap">
        <h1>Factor calculator</h1>
        <div class="box">
            <p>Please enter the number of queries</p>
            <p>
                <input type="text" autofocus id="numTxt">
                <button id="btn">query</button>
            </p>
        </div>
    </div>
</body>
<script type="text/javascript">
     var btn = document.getElementById("btn");
     var numTxt = document.getElementById("numTxt");

     btn.onclick = function(){
        var num = Number(numTxt.value); //Get figures

        if(isNaN(num)){ //isNaN If the input is not a number, return true
            alert("Please enter the correct number.");
            return;
        }

        //Click on the query to jump to the query page
        window.location = "/cha/" + num;
     }
</script>
</html>

You can skip the page.

 

The core is to route/cha/:num. The controller calls all the "small soldiers" and combines the upper services with the API exposed by the small soldiers.

 

cha.ejs view:

<style type="text/css">
    .wrap{...    min-height:400px;}
</style>
<body>
    <div class="wrap">
        <h1>Factor calculator - Result</h1>
        <div class="box">
            <p>The number you inquired is:<%= num %>. Its factors are<%= results.length %>They are:</p>
            <p>This query is time-consuming:<%= time %>Millisecond</p>
            <ul>
                <% 
                    for(var i = 0 ; i < results.length; i++){ 
                %>
                        <li><%= results[i] %></li>
                <% 
                    } 
                %>
            </ul>
        </div>
    </div>
</body>

 

MaiCtrl.js Controller:

var file = require("../models/file.js");
var match = require("../models/match.js");

//Display results page
exports.showCha = function(req,res){
    //Get the number of queries
    var num = req.params.num;
//Render query page, test with false data first
res.render("cha" ,{
    num : num,
    results : [1,2,3,4,5],
});
}

var file = require("../models/file.js");
var match = require("../models/match.js");

exports.showCha = function(req,res){
    //Get the number of queries
    var num = req.params.num;
    var time = new Date();
    //Check whether the file exists
    file.isExist(num , function(exist){
        if(exist){//This number (file) already exists
            //Read this file directly: 
            file.readArray(num , function(arr){
                res.render("cha" ,{ //Dictionaries
                    num : num,
                    results : arr,
                    time : new Date() - time
                });
            });
        }else{//If the file does not exist!
            var arr = math.calcFactor(num);//Calculation!
            //Write an array to a file
            file.writeArray(num , arr , function(){
                res.render("cha" ,{
                    num : num,
                    results : arr,
                    time : new Date() - time
                });
            });
        }
    });
}

Posted by hkucsis on Wed, 15 May 2019 03:09:06 -0700