使用node.js 制作网站前台后台


Posted in Javascript onNovember 13, 2014

node.js  能做什么?我至今也不清楚,他在哪方面应用比较广泛,我没有机会接触到那样的项目。只是因为喜欢,业余时间做了一个网站和后台。深刻领悟到一个道理那就是如果你喜欢一项技术可以玩玩,但是如果用到项目中就必须花些时间去解决很多问题。

使用到的技术:

express + jade

sqlite + sequelize  

redis

1. 关于jade

    支持include。  比如: include ./includes/header  header 是一个局部视图,类似asp.net  用户控件。

    支持extends。 比如: extends ../layout   使用母版页layout。

    for循环也是如此简单。   

each item in userList  (userList 服务器传给前端的变量)

tr

  td #{item.username}

  td #{item.telephone}

  td #{item.email}

  比较喜欢append:

extends ../admin_layout

append head

  link(rel='stylesheet', href='/stylesheets/font-awesome.css')

  script(src='/javascripts/bootstrap.js')

  script(src='/javascripts/bootstrap-wysiwyg.js')

  script(src='/javascripts/jquery.hotkeys.js')

block content

     append 会把脚步和样式全部放在 母版页面head后面。

2.sequelize  实现ORM的框架。 支持sqlite mysql mongodb

   定义模型(文章):

var Article = sequelize.define('Article',{

  title:{

    type:Sequelize.STRING,

    validate:{}

  },

  content:{type:Sequelize.STRING,validate:{}},

  icon:{type:Sequelize.STRING,validate:{}},

  iconname:{type:Sequelize.STRING},

  sequencing:{type:Sequelize.STRING,validate:{}}

},{

  classMethods:{

    //文章分类

    getCountAll:function(objFun){

    }//end getCountAll

  }//end classMethods

});

Article.belongsTo(Category);

 Article.belongsTo(Category);  每一篇文章都有一个分类。

我把分页相关方法写到了初始化sequelize时候。这样每个模型定义时候,都会有这个方法(pageOffset、pageLimit)。

var sequelize = new Sequelize('database', 'username', 'password', {

  // sqlite! now!

  dialect: 'sqlite',

  // the storage engine for sqlite

  // - default ':memory:'

  storage: config.sqlitePath,

  define:{

    classMethods:{

      pageOffset:function(pageNum){

        if(isNaN(pageNum) || pageNum < 1){

          pageNum = 1;  

        }

        return (pageNum - 1) * this.pageLimit();

      },

      pageLimit:function(){

        return 10; //每页显示10条

      },

      totalPages:function(totalNum){

        var total =parseInt((totalNum + this.pageLimit() - 1) / this.pageLimit()),

            arrayTotalPages = [];

        for(var i=1; i<= total; i++){

          arrayTotalPages.push(i);

        }

        return arrayTotalPages;

      }

    },

    instanceMethods:{

    }

  }

});

使用:

Article.findAndCountAll({include:[Category],offset:Article.pageOffset(req.query.pageNum), limit:Article.pageLimit()}).success(function(row){

    res.render('article_list', { 

      title: '文章管理', 

      articleList : row.rows,  

      pages:{

        totalPages:Article.totalPages(row.count),

        currentPage:req.query.pageNum,

        router:'article'

      }

    });

  });

保存模型:

exports.add = function(req, res) {

  var form = new formidable.IncomingForm();

  form.uploadDir = path.join(__dirname, '../files');

  form.keepExtensions = true;

  form.parse(req, function(err, fields,files){

    var //iconPath = files.icon.path,

        //index = iconPath.lastIndexOf('/') <= 0 ? iconPath.lastIndexOf('\\') : iconPath.lastIndexOf('/') ,

        icon = path.basename(files.icon.path), // iconPath.substr(index + 1,iconPath.length - index),

        iconname = files.icon.name;

    var title = fields.title;

        id = fields.articleId;

        title = fields.title,

        content = fields.content,

        mincontent = fields.mincontent,

        sequencing=fields.sequencing == 0 ? 0 : 1,

        category = fields.category;

       Article.sync();  //如果不存在就创建表。

      Category.find(category).success(function(c){

        var article = Article.build({

          title : title, 

          content:content,

          mincontent:mincontent,

          icon:icon,

          iconname:iconname,

          sequencing:sequencing

        });

        article.save()

        .success(function(a){

          a.setCategory(c);

          return res.redirect('/admin/article');

        });

      }); //end category

  });

}

path.basename:

//iconPath = files.icon.path,

//index = iconPath.lastIndexOf('/') <= 0 ? iconPath.lastIndexOf('\\') : iconPath.lastIndexOf('/') ,

icon = <strong>path.basename</strong>(files.icon.path), // iconPath.substr(index + 1,iconPath.length - index),

获取文件名,比如:/a/b/aa.txt   => aa.txt.   最初时候我使用截取字符串,也能实现,但是操作系统不一样的话就会有问题。mac使用'/' . window下面是'\\',我也是部署完成之后才发现的问题 。  后来发现path.basename  直接替换(文档阅读的少,就吃亏啊)。对node.js的好感在加1分。:)

3. redis 缓存经常查询,而且很少变化的数据。

getCountAll:function(objFun){

      redis.get('articles_getCountAll', function(err,reply){

        if(err){

          console.log(err);

          return;

        }

        if(reply === null){

          db.all('SELECT count(articles.CategoryId) as count,categories.name,categories.id FROM articles left join categories on articles.categoryID = categories.id group by articles.CategoryId ', function(err,row){

            redis.set('articles_getCountAll',JSON.stringify(row));

            objFun(row);

          });

        }else{

          objFun(reply);

        }

      });

    这个方法定义在了 model层。 因为是express,所以尽可能的 用mvc方式开发。 其实是route实现了controller层功能(route文件夹,应该命名为为controller)。

Javascript 相关文章推荐
Javascript 阻止javascript事件冒泡,获取控件ID值
Jun 27 Javascript
JavaScript Scoping and Hoisting 翻译
Jul 03 Javascript
JavaScript高级程序设计 阅读笔记(十二) js内置对象Math
Aug 14 Javascript
json属性名为什么要双引号(个人猜测)
Jul 31 Javascript
Bootstrap Search Suggest使用例子
Dec 21 Javascript
微信小程序 动态传参实例详解
Apr 27 Javascript
原生js封装运动框架的示例讲解
Oct 01 Javascript
浅谈Vue响应式(数组变异方法)
May 07 Javascript
通过vue-cli3构建一个SSR应用程序的方法
Sep 13 Javascript
vue权限管理系统的实现代码
Jan 17 Javascript
JS定义函数的几种常用方法小结
May 23 Javascript
JQuery复选框全选效果如何实现
May 08 jQuery
JavaScript 作用域链解析
Nov 13 #Javascript
jQuery $命名冲突解决方案汇总
Nov 13 #Javascript
js获取字符串最后一位方法汇总
Nov 13 #Javascript
实现js保留小数点后N位的代码
Nov 13 #Javascript
详谈jQuery中的this和$(this)
Nov 13 #Javascript
FF(火狐)浏览器无法执行window.close()解决方案
Nov 13 #Javascript
jquery checkbox 勾选的bug问题解决方案与分析
Nov 13 #Javascript
You might like
PHP如何透过ODBC来存取数据库
2006/10/09 PHP
在PHP3中实现SESSION的功能(一)
2006/10/09 PHP
Zend的MVC机制使用分析(一)
2013/05/02 PHP
Smarty使用自定义资源的方法
2015/08/08 PHP
IE浏览器兼容Firefox的JS脚本的代码
2008/10/23 Javascript
在页面中js获取光标/鼠标的坐标及光标的像素坐标
2013/11/11 Javascript
JS正则表达式验证数字代码
2014/01/28 Javascript
jQuery中:last-child选择器用法实例
2014/12/31 Javascript
提交按钮的name='submit'引起的js失效问题及原因
2015/02/25 Javascript
JQuery调用绑定click事件的3种写法
2015/03/28 Javascript
Javascript中arguments和arguments.callee的区别浅析
2015/04/24 Javascript
原生js实现模拟滚动条
2015/06/15 Javascript
Bootstrap table使用方法记录
2017/08/23 Javascript
jQuery简单实现对数组去重及排序操作实例
2017/10/31 jQuery
详解如何用webpack4从零开始构建react开发环境
2019/01/27 Javascript
用js简单提供增删改查接口
2019/05/12 Javascript
js回调函数原理与用法案例分析
2020/03/04 Javascript
Vue.js桌面端自定义滚动条组件之美化滚动条VScroll
2020/12/01 Vue.js
[03:38]TI4西雅图DOTA2前线报道 71专访
2014/07/08 DOTA
[11:42]2018DOTA2国际邀请赛寻真——OG卷土重来
2018/08/17 DOTA
python脚本实现查找webshell的方法
2014/07/31 Python
浅析AST抽象语法树及Python代码实现
2016/06/06 Python
详解Python 序列化Serialize 和 反序列化Deserialize
2017/08/20 Python
酷! 程序员用Python带你玩转冲顶大会
2018/01/17 Python
Python实现的基于优先等级分配糖果问题算法示例
2018/04/25 Python
python 实现A*算法的示例代码
2018/08/13 Python
python leetcode 字符串相乘实例详解
2018/09/03 Python
Python3几个常见问题的处理方法
2019/02/26 Python
tensorflow保持每次训练结果一致的简单实现
2020/02/17 Python
美国儿童珠宝在线零售商:Loveivy
2019/05/22 全球购物
Herschel Supply Co.美国:背包、手提袋及配件
2020/11/24 全球购物
物理系毕业生自荐信
2013/11/01 职场文书
化学工程专业求职信
2014/08/10 职场文书
护士长2014年度工作总结
2014/11/11 职场文书
龙猫观后感
2015/06/09 职场文书
公司考勤管理制度
2015/08/04 职场文书