使用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 相关文章推荐
innerHTML 和 getElementsByName 在IE下面的bug 的解决
Apr 09 Javascript
html+css+js实现xp window界面及有关功能
Mar 26 Javascript
Bootstrap创建可折叠的组件
Feb 23 Javascript
一个字符串中出现次数最多的字符 统计这个次数【实现代码】
Apr 29 Javascript
jquery的ajax提交form表单的两种方法小结(推荐)
May 25 Javascript
AngularJS 模型详细介绍及实例代码
Jul 27 Javascript
Vue.js每天必学之方法与事件处理器
Sep 06 Javascript
Vue数据驱动模拟实现3
Jan 11 Javascript
jQuery UI Grid 模态框中的表格实例代码
Apr 01 jQuery
React Native 通告消息竖向轮播组件的封装
Aug 25 Javascript
vue首次赋值不触发watch的解决方法
Sep 11 Javascript
JS高级程序设计之class继承重点详解
Jul 07 Javascript
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
如何使用FireFox插件FirePHP调试PHP
2013/07/23 PHP
PHP输出多个元素的排列或组合的方法
2017/03/14 PHP
PHP常用算法和数据结构示例(必看篇)
2017/03/15 PHP
PHP面向对象程序设计子类扩展父类(子类重新载入父类)操作详解
2019/06/14 PHP
用showModalDialog弹出页面后,提交表单总是弹出一个新窗口
2009/07/18 Javascript
js+css实现增加表单可用性之提示文字
2013/06/03 Javascript
javascript实现手机震动API代码
2015/08/05 Javascript
php基于redis处理session的方法
2016/03/14 Javascript
详解Angular的内置过滤器和自定义过滤器【推荐】
2016/12/26 Javascript
angularjs过滤器--filter与ng-repeat配合有奇效
2017/04/20 Javascript
基于jQuery实现的Ajax 验证用户名唯一性实例代码
2017/06/28 jQuery
Angular 2父子组件数据传递之@Input和@Output详解(下)
2017/07/05 Javascript
Javascript刷新页面的实例
2017/09/23 Javascript
jQuery中过滤器的基本用法示例
2017/10/11 jQuery
加载 vue 远程代码的组件实例详解
2017/11/20 Javascript
浅谈Redux中间件的实践
2018/07/27 Javascript
自己动手封装一个React Native多级联动
2018/09/19 Javascript
微信小程序非swiper组件实现的自定义伪3D轮播图效果示例
2018/12/11 Javascript
[12:29]《一刀刀一天》之DOTA全时刻19:蝙蝠骑士田伯光再度不举
2014/06/10 DOTA
Python BeautifulSoup中文乱码问题的2种解决方法
2014/04/22 Python
Python中的__new__与__init__魔术方法理解笔记
2014/11/08 Python
Python中的super()方法使用简介
2015/08/14 Python
Python md5与sha1加密算法用法分析
2017/07/14 Python
python操作excel的方法
2018/08/16 Python
numpy中的meshgrid函数的使用
2019/07/31 Python
python名片管理系统开发
2020/06/18 Python
毕业生求职简历的自我评价
2013/10/07 职场文书
行政助理岗位职责范文
2013/12/03 职场文书
表彰大会策划方案
2014/05/13 职场文书
汽车维修求职信
2014/06/15 职场文书
会计学习心得体会
2014/09/09 职场文书
无犯罪记录证明范本
2014/09/15 职场文书
个人存款证明书
2014/10/18 职场文书
本溪关门山导游词
2015/02/09 职场文书
村官个人总结范文
2015/03/03 职场文书
python pandas 解析(读取、写入)CSV 文件的操作方法
2022/12/24 Python