Express+AdminLTE+hbs+Ajax实现局部刷新终极版(第二部分)

上一篇中已经把所有思路都理顺了,这边我们就开始具体编码吧。(如果您有更好的办法,欢迎留言讨论!互相学习!)

我们先来看一下最终完成的效果:

Express+AdminLTE+hbs+Ajax实现局部刷新终极版(第二部分)_第1张图片

一:完整项目目录结构如图所示:

Express+AdminLTE+hbs+Ajax实现局部刷新终极版(第二部分)_第2张图片

二:更换模板引擎为  hbs

2.1  安装 express-hbs

npm i express-hbs

2.2 在app.js中更换模板引擎,并指定母版页位置  如图:

Express+AdminLTE+hbs+Ajax实现局部刷新终极版(第二部分)_第3张图片

 

至此,我们的模板引擎更换完毕,你会发现,在Views文件加下的所有文件,都是以*.hbs结尾的,如果新加文件,请保持后缀一致。

 

2.3 刚才已经配置好了母版页的位置,就是  “/views/layout”  ,现在我们去看看这个母版页里面的内容吧;如下图

Express+AdminLTE+hbs+Ajax实现局部刷新终极版(第二部分)_第4张图片

 

2.4 现在来介绍下母版页,这个母版页是AdminLTE中的精简版,我把多余的部分全部删除。

从图中可以看出,模板分为四个部分: header(头部)、 aside(侧边栏)、 content(中间内容)  和  footer(底部)

其中我们注意到,在中间内容部分,有一个  {{{body}}}  这种写法的意思就是:每次访问具体页面时,会将具体页面替换掉{{{body}}}部分的内容;

例如:我们想访问主页,主页是  views/index.hbs,我们来看看其中的内容:

Express+AdminLTE+hbs+Ajax实现局部刷新终极版(第二部分)_第5张图片

是的,主页里就只有这些代码,当进行访问主页路由的时候,也就是  localhost:3000时,hbs会将整个div自动替换  {{{body}}} 

我们所看到的就会如下:这极大的方便了我们对模板的应用。

Express+AdminLTE+hbs+Ajax实现局部刷新终极版(第二部分)_第6张图片

到目前,我们所有的视图都具备模板了,而且母版页是单独存放的;下面我们来解决无刷新问题;

三:使用ajax实现无刷新页面

首先,我们编写一个公共的js方法,放在  Base.js中,这个方法有两个作用

1:将侧边栏所有的页面切换请求,通过Ajax发送出去,并得到一个html 页面,将中间部分进行填充;

2:成功填充页面后,将当期请求的url更新到地址栏,以便于用户刷新操作;

看一下这个方法:

var ChangePage = function (url) {
    $.ajax({
        type: 'GET',
        url: url,
        data: { c_type: 'page' },
        success: function (res) {
            $("#main_container").html(res);
            var stateObject = {};
            var title = "Wow Title";
            var newUrl = url;
            history.pushState(stateObject, title, newUrl);
        }
    });
}

细心的朋友会发现一个问题,我在ajax请求的时候,给了一个参数:c_type

别忘记了,这里还有一个非常严重的问题没有解决,那就是  通过页面侧边栏发起的页面跳转,我们希望返回的是不带模板页的分布视图!

这里的参数 c_type 就是为了便于后续的区分处理 

 

四:路由中渲染页面的区分处理

 

4.1 来看一下路由渲染页面是如何进行操作的(为了方便,我把所有页面的跳转都写到了index.js路由中,不要像我学习啊,我实在是太懒了)

router.get('/', function(req, res, next) {
  var pageData = {};
  if(req.query.c_type=='page')
  {
    pageData.layout='';
  }
  res.render('index', pageData);
});

首先我们定义了一个对象:pageData,他用来向页面传递数据;

这里当我们发现前端请求的参数里包含一个叫 c_type 的参数,并且值为  page 那么我们就认为他是从页面侧边栏发起的请求

这个时候,我们关键性的一句来了:pageData.layout=''; 这一句的意思就是不使用模板,返回局部视图,从而实现了无刷新;

 

4.2 但是这样的操作太过繁琐,我们岂不是每个路由都需要添加一个类似的判断?太麻烦了吧?于是我们想到了 中间件 ,它可以把每个请求都过滤一下;

我们来看一下中间件的写法:

//拦截器,必须放在静态资源声明之后、路由导航之前
app.use(function (req, res, next) {
  var url = req.query.c_type;
  global.pageData = {
    data:{}
  }
  if (url == "page") {
    global.pageData.layout='';
  }
  console.log(global.pageData)
  next();
});

 

这里我们把每个请求都就进行拦截,如果发现请求中带有  c_type参数,那么我们就定义一个全局对象:global.pageData

并给  pageData.layout 赋值为空;

在每个路由中,我们只需要引用下这个全局变量,就可以实现模板的自由控制:改良后的路由如下:

router.get('/', function(req, res, next) {
  res.render('index', global.pageData);
});

是不是瞬间少了好多代码!

如果你有一些自定义的数据,就可以放到global.pageData中,这里不作过多解释;

到目前,你已经完成了大部分的操作,页面实现了无刷新加载!

 

五:关于页面侧边栏配置,以及样式保留问题

侧边栏的样式完全是AdminLTE中的原始样式,这里你需要稍微观察一下,如果需要添加更多的侧边栏,只需要按照其规则就可以

关于样式保留,这里我们不过多的介绍,下面是完整方法:在  Base.js中

$(".treeview a").click(function () {
    var item = $(this).parent().parent().parent('.treeview');
    var idStr = $(item).attr('id');
    if (idStr != undefined) {
        localStorage.setItem("c_slider", idStr);
    }else
    {
        localStorage.setItem("c_slider", '');
    }
})

$(function () {
    var c_slider = localStorage.c_slider
    if (c_slider != undefined) {
        $("#" + c_slider).addClass("menu-open");
        $("#" + c_slider + ' ul').css('display', 'block');
    }
})

六:完整Demo下载:

https://download.csdn.net/download/tomato2313/10937611(可能还在审核中)

 

 

 

你可能感兴趣的:(NodeJs)