• MEAN 全栈开发 ——实现简单博客


    最近在学习MEAN全栈开发的过程中,写了一个小程序就当练练手熟悉一下怎么去组合强大的功能。

    废话不多说,直接上文件预览:

    整体文件结构:

    其中,public文件夹存放了img,js,css文件,其中的index.js文件用于配置前台路由,routes文件夹存放了后台路由的配置文件,views文件夹存放静态视图文件,app.js文件作为程序的入口,相当于main函数一样。

    前台路由设置:

    public/javascripts/index.js

    /*前端路由处理*/
    //创建服务
    var blogServices = angular.module('blogServices', ['ngResource']);
    //Blog代表上述服务
    blogServices.factory('Blog', ['$resource',
        function($resource){
            return $resource('/api/list/:_id', {_id: '@id'},
                {
                    //默认提供5种方法,在此可以自定义方法;
                }
            );
    }]);
    
    //在模板中注入模块
    var app = angular.module('app', [
        'ngRoute',
        'blogServices'
    ]);
    
    app.directive('focus', function () {
        return {
            restrict: 'A',//限制只可通过属性调用
            link: function (scope, element, attr) {
                element[0].focus();
            }
        }
    });
    
    
    app.config(function ($routeProvider) {
        $routeProvider.
            //自动忽略前面的#
            when('/', {
                templateUrl: 'posts.html',// 当打开链接为 "/", 载入posts.html
                controller: postsCtrl
            }).
            //add
            when('/api/add', {
                templateUrl: 'add.html',
                controller: postCtrl
            }).
            //read
            when('/api/list/:_id',{
                templateUrl: 'read.html',
                controller: readCtrl
            }).
            //modify
            when('/api/modify/:_id', {
                templateUrl: 'modify.html',
                controller: editCtrl
            }).
            //delete
            when('/api/del/:_id',{
                templateUrl: 'posts.html',
                controller: deleteCtrl
            });
        //otherwise({
        //    redirectTo: '/' // 其他情况,跳到链接"/"
        //});
    });
    
    /* 每个路由对应的控制器 */
    // 文章列表控制器
    // 注入Blog服务
    function postsCtrl($scope,Blog) {
        //去后端访问route.get('/list'),返回查找的数据
        $scope.posts = Blog.query();
    }
    
    // 发布文章控制器
    function postCtrl($scope, Blog, $location) {  // 注入$location服务
        $scope.form = {};   // 初始化一个数据模型
        // 提交操作函数
        $scope.form.submit = function () {
            Blog.save({}, $scope.form,function(){
                $location.url('/'); // 返回首页;
            });
        };
    }
    
    // 读取文章控制器
    function readCtrl($scope, Blog, $routeParams){
        // 将获取到的数据 通过$scope绑定成NG的数据模型
        $scope.post = Blog.get({_id:$routeParams._id});
    }
    
    //删除文章控制器
    function deleteCtrl($scope, Blog, $location, $routeParams){
        Blog.delete({_id:$routeParams._id},function(){
            $location.url('/'); // 返回首页;
        });
    }
    
    // 修改文章控制器
    function editCtrl($scope, Blog, $routeParams, $location) {
        //向后台申请数据,写入post模型
        $scope.post = Blog.get({_id:$routeParams._id});
        // 提交操作函数
        $scope.submit = function () {
            Blog.save({_id: $routeParams._id},$scope.post,function(){
                $location.url('/'); // 返回首页
            });
        };
    }
    
    /* $http方法 */
    /* 文章列表控制器
    function postsCtrl($scope, $http) {    // 注入$Http服务,类似于jquery的ajax
        //去后端访问route.get('/list'),返回查找的数据
        $http.get('/api/list').success(function (data) {
            $scope.posts = data; // 将获得的数据保存到NG的数据模型posts里
        });
    }
     发布文章控制器
    function postCtrl($scope, $http, $location) {  // 注入$location服务
        $scope.form = {};   // 初始化一个NG数据模型
        // 提交操作函数
        $scope.form.submit = function () {
            $http.post('/api/add', $scope.form).success(function () {
                $location.url('/'); // 返回首页
            });
        };
    }
    // 读取文章控制器
    function readCtrl($scope,$http, $routeParams){
        $http.get('/api/list/' + $routeParams._id).success(function(data){
            $scope.post = data; // 将获取到的数据 通过$scope绑定成NG的数据模型
        });
    }
    // 修改文章控制器
    function editCtrl($scope, $http, $routeParams, $location) {  // 注入$location服务
        //向后台申请数据
        $http.get('/api/modify/' + $routeParams._id).success(function (data){
            //将数据存入post
            $scope.post = data;
        });
    
        $scope.form = {};   // 初始化一个NG数据模型
        // 提交操作函数
        $scope.form.submit = function () {
            $http.post('/api/modify/' + $routeParams._id, $scope.post).success(function () {
                $location.url('/'); // 返回首页
            });
        };
    }
    
    //删除文章控制器
    function deleteCtrl($scope, $http, $location, $routeParams){
        $http.get('/api/del/' +  $routeParams._id).success(function () {
            $location.url('/'); // 返回首页
        });
    }*/
    
    // 启动模块
    angular.bootstrap(document, ['app']);
    

    用了两种方法去实现,开始用了$http去写路由(见注释部分),最后改为使用$resource去管理API,这里需要注意一点,只用服务端按照RESTful的方式工作的时候,才可以使用Angular资源。

    服务端路由

    /routes/index.js

    'use strict';
    var express = require('express');
    var router = express.Router();
    var mongoose = require('mongoose');
    var model = require('./model');
    var Demo = model.Demo;
    mongoose.connect('mongodb://localhost/monkey');
    /*这里的路由是用来处理访问为'xxx'的请求*/
    /* 查找数据库数据.*/
    router.get('/api/list',function(req,res,next){
    		console.log("This is finding data!");
    		Demo.find({}).sort({createTime: -1}).exec(function (err, docs) {
    			res.json(docs);
    		});
    });
    
    /*跳转到添加页面,创建新纪录*/
    router.post('/api/list',function(req, res){
    	var demo = new Demo(req.body);
    	demo.save(function(err,doc){
    		if (err) {
    			console.log(err);
    			res.send(err);
    		}
    		else {
    			console.log('create');
    			console.log(doc);
    			res.json({status: 'done'});
    		}
    	});
    });
    
    //根据id查找相应的记录
    router.get('/api/list/:_id',function(req,res){
    	var id = req.params._id;
    	console.log(id);
    	console.log('Now start to read!');
    	if(id) {
    		//返回文档
    		Demo.findOne({_id: id}).exec(function (err, docs) {
    			console.log(docs);
    			res.json(docs);
    		});
    	}
    });
    
    // 根据id删除相应的记录
    router.delete('/api/list/:_id',function(req, res){
    	var id = req.params._id;
    	console.log('delete');
    	console.log(id);
    	if(id) {
    		console.log('delete id = ' + id);
    		Demo.findByIdAndRemove(id, function(err, docs) {
    			console.log(docs);
    			res.json(docs);
    		});
    	}
    });
    
    /*查询对应修改记录,并跳转到修改页面
    router.get('/api/modify/:_id',function(req, res) {
    	var id = req.params._id;
    	console.log('id = ' + id);
    	console.log('Now start to modify!');
    	Demo.findOne({_id: id}).exec(function (err, docs) {
    		console.log(docs);
    		res.json(docs);
    	});
    });*/
    
    //修改相应的值
    router.post('/api/list/:_id',function(req, res) {
    	var demo = new Demo(req.body);
    	var id = req.params._id; //因为是post提交,所以不用query获取id
    	if(id) {
    		console.log('----update');
    		console.log(demo);
    		Demo.findByIdAndUpdate(id, demo,function(err, docs) {
    			res.json({status: 'done'});
    		});
    	}
    });
    
    module.exports = router;
    

      这里的作用是来处理对应URL的前台访问,作为对应的处理函数。

    定义数据库

    /routes/model.js

    var mongoose = require('mongoose');
    var Schema = mongoose.Schema;
    
    var demoSchema = new Schema({
    	uid : {
    		required:true,
    		type:String,
    		unique:true,
    		trim:true
    	},
    	title: {
    		type:String,
    		required:true
    	},
    	content: {
    		type:String,
    		required:true
    	},
    	createTime : {
    		type: Date,
    		default: Date.now
    	}
    });
    
    Demo = mongoose.model('Demo',demoSchema);
    exports.Demo = Demo;
    

    视图文件

    views//index.html

    <!DOCTYPE HTML>
    <html lang="zh-CN">
    <head>
    	<meta charset="UTF-8">
    	<title>MAEN BLOG</title>
        <link rel="stylesheet" href="stylesheets/common.css" />
        <link rel="stylesheet" href="stylesheets/index.css" />
    </head>
    <body>
        <header>
            <h1 id="logo"><a href="#">BLOG List</a></h1>
        </header>
    
        <div id="main">
            <!-- 路由区域 -->
            <ng-view />
        </div>
    
    	<!-- javascript-->
    	<script src="javascripts/plugins/angular/angular.min.js" type="text/javascript"></script>
    	<script src="javascripts/plugins/angular-route/angular-route.min.js" type="text/javascript"></script>
        <script src="javascripts/plugins/angular-resource/angular-resource.js" type="text/javascript"></script>
        <script src="javascripts/index.js"></script>
    </body>
    </html>
    

    views/add.html

    <form id="post" ng-submit="form.submit()">
        <input ng-model="form.uid" focus type="text" placeholder="文章ID" />
        <input ng-model="form.title"  type="text" placeholder="标题" />
        <textarea ng-model="form.content" placeholder="正文"></textarea>
        <div>
            <button class="btn btn-danger pull-right" type="submit">提交发布</button>
        </div>
    </form>
    

    views/modify.html

    <form id="modify" ng-submit="submit()">
        <div>
            <div>{{post.createTime|date: 'yyyy-MM-dd HH:mm:ss'}}</div>
            <input ng-model="post.title" focus type="text">
            <textarea ng-model="post.content"></textarea>
            <div>
                <button class="btn btn-danger pull-right" type="submit">save</button>
            </div>
        </div>
    </form>
    

    views/posts.html

    <table>
        <tr>
            <th>题目 -
                <button class="btn btn-danger"><a href="/#/api/add">发表文章</a></button>
            </th>
            <th>时间</th>
            <th></th>
            <th></th>
        </tr>
        
        <!-- ng-repeat可以根据NG数据模型遍历数据,相当于forEeach -->
        <tr ng-repeat="post in posts">
            <td><a href="/#/api/list/{{post._id}}">{{ post.title }}</a></td>
            <!-- 用filter过滤器,转换了显示的时间格式 -->
            <td class="text-muted">{{ post.createTime|date: 'yyyy-MM-dd HH:mm:ss'}}</td>
            <td><a href="/#/api/modify/{{post._id}}">修改</a></td>
            <td><a href="/#/api/del/{{post._id}}">删除</a></td>
        </tr>
    
       <!-- ng-hide表示,当文章列表有内容,将不显示这里 -->
        <tr ng-hide="posts.length">
            <td colspan="2" class="text-muted text-center">没有文章哦</td>
        </tr>
    </table>
    

    views/read.html

    <form id="read" ng-submit="form.submit()">
        <div>
            <div>
                {{post.createTime|date: 'yyyy-MM-dd HH:mm:ss'}}
            </div>
            <div>
                <input ng-model="post.title" focus type="text">
            </div>
            <textarea ng-model="post.content"></textarea>
            <div>
                <a href="#" class="pull-right">back</a>
            </div>
        </div>
    </form>
    

    引导文件

    app.js

    var express = require('express');
    var path = require('path');
    var favicon = require('serve-favicon');
    var logger = require('morgan');
    var cookieParser = require('cookie-parser');
    var bodyParser = require('body-parser');
    
    var routes = require('./routes');
    var user = require('./routes/user');
    var http = require('http');
    var ejs = require('ejs');
    var app = express();
    
    // view engine setup
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'html');
    app.engine('html',ejs.__express);
    
    // uncomment after placing your favicon in /public
    //app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
    app.use(logger('dev'));
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: false }));
    app.use(cookieParser());
    app.use(express.static(path.join(__dirname, 'public')));
    app.use(express.static(path.join(__dirname, 'views')));
    app.use('/',routes);
    app.use('/users',user.list);
    
    // catch 404 and forward to error handler
    app.use(function(req, res, next) {
      var err = new Error('Not Found');
      err.status = 404;
      next(err);
    });
    
    // error handlers
    
    // development error handler
    // will print stacktrace
    if (app.get('env') === 'development') {
      app.use(function(err, req, res, next) {
        res.status(err.status || 500);
        res.render('error', {
          message: err.message,
          error: err
        });
      });
    }
    
    // production error handler
    // no stacktraces leaked to user
    app.use(function(err, req, res, next) {
      res.status(err.status || 500);
      res.render('error', {
        message: err.message,
        error: {}
      });
    });
    module.exports = app;
    

      

    现在的程度只能做到这样子,希望以后的学习中会不断优化。

  • 相关阅读:
    haproxy tcp 反向代理
    c# 字节高低位
    Mac Launchpad图标调整
    vsftp 777权限
    centos7下tomcat7 或tomcat8启动超慢原因
    mysql连接com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link
    Mac mysql 运行sql文件中文乱码的问题
    Mac Mysql [ERR] 2006
    记一次部署java项目的问题
    典型的响应式布局实例代码
  • 原文地址:https://www.cnblogs.com/nanchen/p/4786877.html
Copyright © 2020-2023  润新知