后台管理系统项目总结(2)

后台管理系统项目总结(2)

1.匿名模块和具名模块以及非模块改造成模块化

1.1匿名模块

  • 之前使用的除了jquery之外,其它的都是我们自己定义的,这些都是匿名模块(没有自己真正的字)

1.2具有模块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
像jquery这样的具名模块必须使用人家定义好的模块名,不能再添加其它的别名
require.config({
baseUrl:'/',
paths:{
'a':'02-具名模块的使用/js/a',
'bbbb':'02-具名模块的使用/js/b', // 虽然这个模块没有名称,但是前面的bbbb就相当于是一个别名
'c':'02-具名模块的使用/js/c',
'd':'02-具名模块的使用/js/module/d',
'jquery':'02-具名模块的使用/js/jquery/jquery.min' // 具名模块的使用,不能乱写,必须写之前定义好的名称
},
shim:{
'boostrap':{
deps:['jquery']
}
}
});
require(['a','bbbb','jquery'],function (obj1,obj2,$){
console.log($('p'));
});

1.3将非模块改成模块化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
普通函数文件内的代码
// function test(){
// alert('这是一个正常的函数文件,不是模块化的定义方式....');
// }
var aaa = "这是普通的文件中的变量字符串";
使用模块化加载 ,并使用函数或是变量:
require.config({
baseUrl:'/',
paths:{
'm':'03-非模块改成模块化/js/m'
},
shim:{
'boostrap':{
deps:['jquery']
},
'm':{
//exports:'test' // 一定要用双引号引起来,是一个字符串形式,这个名称一定要和非模块文件中的函数名或是变量名称一致
exports:'aaa'
}
}
});
require(['m'],function (fn){
// fn();
console.log(fn);
});

2.提取公共模块

1.提取公共模块信息 把script.html中的require.config中的信息,提取到单独的文件当中

2.在public里面新建一个libs的文件夹,再新建一个config.js的文件,把之前配置信息放在里面

3.把require.js由原来的public/assets/require文件夹中,剪切到当前libs的文件当中

4.把common文件夹中script.html文件中的路径修改成如下格式:

1
2
<script src="/views/public/libs/require.js"></script>
<script src="/views/public/libs/config.js"></script>

3.侧边栏的交互功能

  • 1.创建并切换到分支 navs下面,因为要做侧边栏中课程管理和系统设置的交互功能,代码如下:
1
git checkout -b navs // 在主分支中输入此命令,创建并切换到navs分支
  • 2.到public->js->dashboard/common.js中,先把此文件上面的代码注释写清楚(登陆,登陆后的用户名和头像的渲染,退出功能等),然后再写侧边栏的交互功能的代码,代码如下:
1
2
3
4
5
console.log($(".navs a+ul").prev());先测试一下,是否获取到了对象
$(".navs a+ul").prev().on("click",function (){
//上面是给和ul平级的a标签注册事件
$(this).next().slideToggle();//通过当前对象,找到下一个元素,也就是ul,让它进行下拉菜单的切换
})
  • 3.在navs分支中的操作,及时的进行提交并保存操作记录,代码如下:
1
2
git add -A
git commit -m '添加了侧边栏课程管理和系列设置的交互功能'
  • 4.切换到主分支master并合并分支
1
2
git checkout master
git merge navs 将之前的navs分支合并到当前的主分支当中

4.修改侧边栏的结构

  • 1.创建分支asideUpdate
1
git checkout -b asideUpdate
  • 2.修改侧边栏的模块,就是添加一些内容或是删除一些内容
1
在侧边栏的地方,修改样式结构,改成和参考网站一样,只保留 仪表盘、讲师管理、分类管理、课程管理
  • 3.及时提交保存
1
2
git add -A 提交到暂存区
git commit -m '需求改变,模块重新划分'

5.讲师管理之显示讲师列表信息

1.先创建分支teacher_mananger并切换到此分支下面

1
git checkout -b teacher_manager

2.aside.html中修改讲师管理的链接

1
2
3
4
5
6
<li>
<a href="/views/teacher/list">
<i class="fa fa-bell"></i>
讲师管理
</a>
</li>

3.在teacher文件夹下,找到list.html文件,修改里面的文件引入

1
2
3
4
<?php include '/views/common/css.html'?> // 样式
<?php include '/views/common/aside.html'?> //侧边栏
<?php include '/views/common/head.html'?> //头部
<?php include '/views/common/script.html'?> //script

4.js文件夹下面新建teacher文件夹,再新建list.js文件,书写代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
define(['jquery','template'],function ($,template){
$.ajax({
url:'/api/teacher',
type:'get',
success:function (data){
if(data.code==200){
// 用模板来渲染数据
var htmlStr = template('tc_list_tpl',data);
$("#tc_list_tBody").html(htmlStr);
}
}
})
})

5.在teacher文件夹下面的list.html拼接模板,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<script type="text/template" id="tc_list_tpl">
{{each result as v i}}
<tr>
<td>{{i+1}}</td>
<td>{{v.tc_name}}</td>
<td>{{v.tc_roster}}</td>
<td>{{v.tc_birthday}}</td>
{{if v.tc_gender==1}}
<td>男</td>
{{else}}
<td>女</td>
{{/if}}
<td>{{v.tc_cellphone}}</td>
<td>
<a href="#teacherModal" data-toggle="modal" class="btn btn-info btn-xs">查 看</a>
<a href="./teacher_add.html" class="btn btn-info btn-xs">编 辑</a>
<a href="javascript:;" class="btn btn-warning btn-xs">注 销</a>
</td>
</tr>
{{/each}}
</script>

6.在teacher文件夹下的list.html页面中,调用 模块,代码如下:

1
2
3
4
<script>
// 这种是某个文件的模块的话,不是公共的模块的话,没必要写在config.js配置文件当中,直接写路径即可
require(['js/teacher/list']); // 在此处调用模块
</script>

6.讲师管理之查看某个讲师

1.给查看按钮 注册事件

1
2
3
4
//讲师查看信息 是用事件委托来注册事件,否则不起效果
$('#tc_list_tBody').on('click','a.check-info',function (){
alert(123);
})

2.要把之前讲师列表的每一个id都存储起来

1
2
3
4
5
<td data-id="{{v.tc_id}}"> //此处添加一个自定义属性,来存储每一个讲师的id
<a href="#" id="check-info" class="check-info btn btn-info btn-xs">查 看</a>
<a href="./teacher_add.html" class="btn btn-info btn-xs">编 辑</a>
<a href="javascript:;" class="btn btn-warning btn-xs">注 销</a>
</td>

3.要发送ajax请求,获取数据,以下代码 是在list.js中书写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$('#tc_list_tBody').on('click','a.check-info',function (){
// alert(123);
var id = $(this).parent().attr('data-id');
$.ajax({
url:'/api/teacher/view',
type:'get',
data:{tc_id:id},
success:function (info){
if(info.code ==200){
//要渲染模板
var htmlStr = template('tc_info_tpl',info.result);
$('#teacherModal tbody').html(htmlStr);
$('#teacherModal').modal(); //让模态框弹出来
}
}
})
})

4.渲染页面中的模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<script type="text/template" id="tc_info_tpl">
<tr>
<th>姓名:</th><td>{{tc_name}}</td>
<th>职位:</th><td colspan="3">讲师</td>
<td rowspan="4" width="128">
<div class="avatar">
<img src="{{tc_avatar==''?'/views/public/uploads/monkey.png':tc_avatar}}" alt="">
</div>
</td>
/tr>
<tr>
<th>花名:</th><td>{{tc_roster}}</td>
<th>出生日期:</th><td colspan="3">{{tc_birthday}}</td>
</tr>
<tr>
<th>性别:</th><td>{{tc_gender}}</td>
<th>加入日期</th><td colspan="3">{{tc_join_date}}</td>
</tr>
<tr>
<th>手机号码:</th><td colspan="2">{{tc_cellphone}}</td>
<th>邮箱:</th><td colspan="2">{{tc_email}}</td>
</tr>
<tr>
<th>籍贯:</th><td colspan="6">{{tc_hometown}}</td>
</tr>
<tr>
<td colspan="7">
<div class="introduce">
{{tc_introduce}}
</div>
</td>
</tr>
</script>

7.讲师的注销和启用

思路:

1
2
1. 当单击按钮的时候,要向服务器发送请求,携带一个id和status
2. 如果当前的status是0(表示是一个启用的状态,按钮上面的字显示的是注销)的话,到服务器后,就应该返回一个1让客户端的这个按钮变成注销的状态,按钮的字显示启用。

1.在list.html页面中给注销的按钮添加一个类.btnHandle

2.在讲师列表渲染的时候,根据返回来的tc_status判断当前的按钮显示的文字,如果是0的话则显示注销,如果是 1的话,则显示启用,在list.html文件当中修改,代码如下:

1
2
3
4
5
6
7
8
9
<td data-id="{{v.tc_id}}">
<a href="#" class="btn btn-info btn-xs check-info">查 看</a>
<a href="./teacher_add.html" class="btn btn-info btn-xs">编 辑</a>
{{if v.tc_status==0}}
<a href="javascript:;" data-status="{{v.tc_status}}" class="btn btn-warning btn-xs btnHandle">注 销</a>
{{else}}
<a href="javascript:;" data-status="{{v.tc_status}}" class="btn btn-warning btn-xs btnHandle">启 用</a>
{{/if}}
</td>

3.在list.js文件当中,给按钮注册事件,发送ajax请求,请求回来数据之后,要及时的更新按钮的tc_status值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
$("#tc_list_tBody").on("click","a.btnHandle",function (){
//因为这个按钮是在模板上,相当于动态创建出来的,因此需要使用委托 来注册事件,就是把事件注册给父元素,通过子元素来触发执行
// alert(123);
// var that = this;
var _this = $(this);//将当前的按钮对象存在变量当中
$.ajax({
url:'/api/teacher/handle',
type:'post',
data:{tc_id:$(this).parent().attr('data-id'),tc_status:$(this).attr('data-status')},
//注意这个地方,最好是用attr,因为下面还要设置呢,先不要用data了,否则没有效果。。。
success:function (res){
if(res.code==200){
if(res.result.tc_status==1){
_this.text('启 用'); // 改变当前按钮的文字
}else {
_this.text('注 销');
_this.attr('data-status',res.result.tc_status);
}
}
}
})
})

4.保存并提交

8.讲师编辑功能的实现

1.当单击编辑按钮的时候,要跳转到编辑页面,而添加讲师功能的页面和此页面是一致的,因此需要修改此页面的名称为manager.html

2.在list.html页面的模板中,修改编辑按钮的路径,因为跳转之后,需要用当前的id来查询对应的讲师信息,在当前页面渲染出来,因为在路径后面需要拼接字符串,代码为:

1
2
<a href="/teacher/manager?tc_id={{v.tc_id}}" class="btn btn-info btn-xs">编 辑</a>
{{if v.tc_status==0}}

3.在js/teacher的文件夹下面,新建一个manager.js的文件,定义并编辑模块。

4.根据当前的网址信息,获取网址?后面的字符串,拼接成对象,然后根据id,发送ajax请求,获取对应的信息,渲染出来,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
define(['jquery','template'],function ($,template) {
var search = location.search;
//?tc_id=201&abc=ljalsjfalj
search = search.slice(1);//从索引为1的地方开始截取,如果没有第二个参数,则默认是截取到最后
//tc_id=201&abc=ljalsjfalj
var searchArr = search.split('&');
console.log(searchArr);
// 要想很方便的获取到对应的属性值 ,最好的办法应该是放到对象当中,用对象.的方式来获取
var o = {}; //
// js是弱类型的动态语言
// 弱类型就是对变量当中存储的数据类型要求不严格,js中的变量可以存储任意的数据类型,只在在直接执行使用这个变量的值的时候,才会去区分里面到底存了什么值
//动态: 1. js中的数组是动态可变的 2. js中可以随时给动态的给对象添加属性和方法
for (var i = 0; i < searchArr.length; i++) {
var temp = searchArr[i].split('=');
// console.log(temp);
o[temp[0]] = temp[1];// 将每一个数组中的第一项做为对象的属性,将第二项做为属性值,存到对象
}
// console.log(o.tc_id);
// 根据id发送请求,去服务器请求数据
$.ajax({
url:'/api/teacher/edit',
type:'get',
data:{tc_id:o.tc_id},
success:function (res){
if(res.code==200){
res.result.title="讲师编辑"; //添加两个属性
res.result.saveBtnText = '保存';
var htmlStr = template('tc_edit_tpl',res.result);
$('.teacher').html(htmlStr);
}
}
})
})

5.把manager.html页面的form表单做为模板,进行修改,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<script type="text/template" id="tc_edit_tpl">
<!-- 面包屑 -->
<ol class="breadcrumb">
<li><a href="javascript:;">讲师管理</a></li>
<li class="active">{{title}}</li>
</ol>
<div class="teacher-add">
<form action="" class="form-horizontal col-md-offset-2">
<input type="hidden" name="tc_id" value="{{tc_id}}">
<div class="form-group">
<label for="" class="col-md-3 control-label">姓名</label>
<div class="col-md-4">
<input type="text" name="tc_name" value="{{tc_name}}" class="form-control input-sm" placeholder="讲师名称">
</div>
</div>
{{if !tc_id}}
<div class="form-group">
<label for="" class="col-md-3 control-label">密码</label>
<div class="col-md-4">
<input type="password" name="tc_pass" class="form-control input-sm">
</div>
</div>
{{/if}}
<div class="form-group">
<label for="" class="col-md-3 control-label">入职时间</label>
<div class="col-md-4">
<input type="text" name="tc_join_date" value="{{tc_join_date}}" class="form-control input-sm">
</div>
</div>
<div class="form-group">
<label for="" class="col-md-3 control-label">类型</label>
<div class="col-md-2">
<select name="tc_type" class="form-control input-sm">
<option value="1" {{if tc_type==1}}selected{{/if}}>讲师</option>
<option value="0" {{if tc_type==0}}selected{{/if}}>管理员</option>
</select>
</div>
</div>
<div class="form-group">
<label for="" class="col-md-3 control-label">性别</label>
<div class="col-md-4">
<label class="radio-inline">
<input type="radio" name="tc_gender" value="1" {{if tc_gender==1}}checked{{/if}}> 男
</label>
<label class="radio-inline">
<input name="tc_gender" type="radio" value="0" {{if tc_gender==0}}checked{{/if}}> 女
</label>
</div>
</div>
<div class="form-group">
<div class="col-md-7">
<button type="submit" class="btn btn-success btn-sm pull-right btnSave"> {{saveBtnText}} </button>
</div>
</div>
</form>
</div>
</script>

6.当单击保存按钮的时候,要发送ajax请求,来保存当前重新编辑过的内容,此时 使用的是.ajaxSubmit(),这个请求的好处,是直接从表单获取数据,不用自己手动获取数据了,代码如下:

1
2
3
4
5
6
7
8
9
10
11
$(".teacher").on("click",'.btnSave',function (){
$('form').ajaxSubmit({
url:/api/teacher/update,
type:'post',
success:function (res){
alert('提交成功...');
location.href='/teacher/list';//跳转到讲师列表页
}
})
return false;
})

7.保存上述操作,并用git提交到版本仓库。

9.讲师添加功能的实现

1.当单击讲添加按钮的时候,页面会根据里面的链接进行跳转,而此页面会加载 manager.js模块,此模块中的代码需要地址栏中的id号,但是添加按钮的跳转,地址栏中是没有id号的,因此会报错,解决的办法就是在manager.js中做一个判断,如果有id,则说明是编辑按钮的跳转,如果没有,则是添加按钮的跳转。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
define(['jquery','template' ,'js/util','form','datepicker','datepickerzh'],function ($,template,util,form,dp,dpzh) {
// var obj = util.queryString();
// console.log(obj.tc_id);
// 根据id发送请求,去服务器请求数据
// 在这里根据id判断一下,如果有id号,说明是一个编辑的功能,如果没有id说明是添加的功能
if(util.queryString().tc_id){
$.ajax({
url:'/api/teacher/edit',
type:'get',
// data:{tc_id:o.tc_id},
// data:{tc_id:obj.tc_id},
data:{tc_id:util.queryString().tc_id},
success:function (res){
if(res.code==200){
res.result.title="讲师编辑"; //添加两个属性
res.result.saveBtnText = '保存';
var htmlStr = template('tc_edit_tpl',res.result);
$('.teacher').html(htmlStr);
//加载日期插件
$('input[name=tc_join_date]').datepicker({
format:'yyyy-mm-dd',
language:'zh-CN'
});
}
}
});
// $('form').ajaxForm(function (){
// // 与ajax的用法几乎一致,与ajax不同的是,此事件,不再需要我们手动的传参,它会自动的将此form表单下面的一切数据用ajax的方式进行提交
// url:'/api/teacher/update',
// type:'post'
// })
// 依赖于jquery的一个新的插件,叫jquery.form,只要调用这个插件,就可以将表单里面的数据,全部自动提交
$(".teacher").on("click",'.btnSave',function (){
$('form').ajaxSubmit({
url:'/api/teacher/update',
type:'post',
success:function (res){
alert('保存成功...');
location.href='/teacher/list';
}
})
return false;
})
}else {//
// 重新渲染页面,只渲染有数据显示的部分
var htmlStr = template('tc_edit_tpl',{
title:'讲师添加',
saveBtnText:'添加',
tc_gender:1
});
$('.teacher').html(htmlStr);
$(".teacher").on("click",'.btnSave',function (){
$('form').ajaxSubmit({
url:'/api/teacher/add',
type:'post',
success:function (res){
alert('提交成功...');
location.href='/teacher/list';
}
})
return false;
})
}
})

2.其中有两个地方的代码是重复的,因此需要封装到函数中,封装完后的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
define(['jquery','template' ,'js/util','form','datepicker','datepickerzh'],function ($,template,util,form,dp,dpzh) {
// var obj = util.queryString();
// console.log(obj.tc_id);
// 根据id发送请求,去服务器请求数据
// 在这里根据id判断一下,如果有id号,说明是一个编辑的功能,如果没有id说明是添加的功能
if(util.queryString().tc_id){
$.ajax({
url:'/api/teacher/edit',
type:'get',
// data:{tc_id:o.tc_id},
// data:{tc_id:obj.tc_id},
data:{tc_id:util.queryString().tc_id},
success:function (res){
if(res.code==200){
res.result.title="讲师编辑"; //添加两个属性
res.result.saveBtnText = '保存';
var htmlStr = template('tc_edit_tpl',res.result);
$('.teacher').html(htmlStr);
//加载日期插件
$('input[name=tc_join_date]').datepicker({
format:'yyyy-mm-dd',
language:'zh-CN'
});
}
}
});
submitAjax('/api/teacher/update');
}else {//
var htmlStr = template('tc_edit_tpl',{
title:'讲师编辑',
saveBtnText:'添加',
tc_gender:1
});
$('.teacher').html(htmlStr);
$('input[name=tc_join_date]').datepicker({
format:'yyyy-mm-dd',
language:'zh-CN'
});
submitAjax('/api/teacher/add');
}
function submitAjax(url){
$(".teacher").on("click",'.btnSave',function (){
$('form').ajaxSubmit({
url:url,
type:'post',
success:function (res){
alert('提交成功...');
location.href='/teacher/list';
}
})
return false;
})
}
//还是注册事件,和上面的是一样的提交数据 还是ajaxSubmit来提交数据
})

10.日期插件的使用

1.先在需要使用日期插件的页面引入css,也就是在manager.html页面中引入静态文件

1
<link rel="stylesheet" href="/views/public/assets/bootstrap-datepicker/css/bootstrap-datepicker.css">

2.在config.js配置文件中,引入其对应的js文件,中文格式的文件一并引入进来

1
2
'datepicker':'assets/bootstrap-datepicker/js/bootstrap-datepicker',
'datepickerzh':'assets/bootstrap-datepicker/locales/bootstrap-datepicker.zh-CN.min'

3.在manager.js模块使用的时候,先引入模块,然后在页面模板渲染完毕之后 ,调用日期插件方法

1
2
3
4
$('input[name=tc_join_date]').datepicker({
format:'yyyy-mm-dd', // 让插件按正常的年月日的格式显示
language:'zh-CN' // 将插件显示为汉化的状态
});

4.注意datepickerzh插件不支持模块化,需要添加依赖:

1
2
3
4
5
6
7
8
shim:{
'bootstrap':{
deps:['jquery']
},
'datepickerzh':{
deps:['jquery']
}
}

之前完成 了的任务

1
2
3
4
5
6
7
8
9
10
11
1. 搭建目录结构(分门别类放在各自的文件夹内)
2. 配置hosts文件
3. 根据输入信息进行页面导航(index.php)
4. 提取各页面中的公共部分到单独的文件当中
5. 解决跨域(设置反向代理)
6. 完成普通登陆功能并渲染左侧头像和用户名
7. 使用模块化修改原来的文件,进行模块化开发
8. 完成退出功能
9. 渲染讲师列表
10. 注销和启用按钮的完成
11. 编辑按钮的实现
-------------本文结束感谢您的阅读-------------