目标

  • 运用AngularJS前端框架的常用指令
  • 完成品牌管理的列表功能
  • 完成品牌管理的分页列表功能
  • 完成品牌管理的增加功能
  • 完成品牌管理的修改功能
  • 完成品牌管理的删除功能
  • 完成品牌管理的条件查询功能

1. 入门

1. 简介

AngularJS 诞生于2009年,由Misko Hevery 等人创建,后为Google所收购。是一款优秀的前端JS框架,已经被用于Google的多款产品当中。AngularJS有着诸多特性,最为核心的是:MVC、模块化、自动化双向数据绑定、依赖注入等等。

2. 四大特征

1. mvc模式

Angular遵循软件工程的MVC模式,并鼓励展现,数据,和逻辑组件之间的松耦合.通过依赖注入(dependency injection),Angular为客户端的Web应用带来了传统服务端的服务,例如独立于视图的控制。 因此,后端减少了许多负担,产生了更轻的Web应用。

Model:数据,其实就是angular变量($scope.XX);

View: 数据的呈现,Html+Directive(指令);

Controller: 操作数据,就是function,数据的增删改查

2. 双向绑定

AngularJS是建立在这样的信念上的:即声明式编程应该用于构建用户界面以及编写软件构建,而指令式编程非常适合来表示业务逻辑。框架采用并扩展了传统HTML,通过双向的数据绑定来适应动态内容,双向的数据绑定允许模型和视图之间的自动同步。因此,AngularJS使得对DOM的操作不再重要并提升了可测试性。

3. 依赖注入

依赖注入(Dependency Injection,简称DI)是一种设计模式, 指某个对象依赖的其他对象无需手工创建,只需要“吼一嗓子”,则此对象在创建时,其依赖的对象由框架来自动创建并注入进来,其实就是最少知识法则;模块中所有的service和provider两类对象,都可以根据形参名称实现DI.

4. 模块化设计

高内聚低耦合法则

  1. 官方提供的模块 ng、ngRoute、ngAnimate
  2. 用户自定义的模块 angular.module(‘模块名’,[ ])

2. 入门小demo

1. 表达式

<!DOCTYPE html>
<html>
<head><title>angularJS入门小demo-表达式</title><script src="angular.min.js"></script>
</head>
<body ng-app>
{{100+100}}
</body>
</html>

2. 双向绑定

<!DOCTYPE html>
<html>
<head><title>angularJS入门小demo02-双向绑定</title><script src="angular.min.js"></script>
</head>
<body ng-app>
请输入姓名:<input ng-model="name">
<input ng-model="name">
{{name}}
</body>
</html>

3. 初始化指令

<!DOCTYPE html>
<html>
<head><title>angularJS入门小demo03-初始化指令</title><script src="angular.min.js"></script>
</head>
<body ng-app ng-init="name='梁静茹'">
请输入姓名:<input ng-model="name">
<input ng-model="name">
{{name}}
</body>
</html>

也可以调用方法

4. 控制器

<!DOCTYPE html>
<html>
<head><title>angularJS入门小demo04-控制器</title><script src="angular.min.js"></script><script>// 建立模块var app = angular.module("myApp",[]);// 创建控制器 $scope就是控制层与视图层之间交换数据的桥梁app.controller("myController",function($scope){$scope.add=function(){return parseInt($scope.x)+parseInt($scope.y);}});</script>
</head>
<body ng-app="myApp" ng-controller="myController">第一个数:<input ng-model="x">
第二个数:<input ng-model="y">
{{add()}}
</body>
</html>

5. 事件指令

<!DOCTYPE html>
<html>
<head><title>angularJS入门小demo05-事件指令</title><script src="angular.min.js"></script><script>// 建立模块var app = angular.module("myApp",[]);// 创建控制器 $scope就是控制层与视图层之间交换数据的桥梁app.controller("myController",function($scope){$scope.add=function(){$scope.z = parseInt($scope.x)+parseInt($scope.y);}});</script>
</head>
<body ng-app="myApp" ng-controller="myController">第一个数:<input ng-model="x">
第二个数:<input ng-model="y">
<br/>
<button ng-click="add()">运算</button>
<br/>
运算结果:{{z}}
</body>
</html>

6. 循环数组

<!DOCTYPE html>
<html>
<head><title>angularJS入门小demo06-循环数组</title><script src="angular.min.js"></script><script>// 建立模块var app = angular.module("myApp",[]);// 创建控制器 $scope就是控制层与视图层之间交换数据的桥梁app.controller("myController",function($scope){$scope.list = [1,2,3,4,55];});</script>
</head>
<body ng-app="myApp" ng-controller="myController"><table><tr ng-repeat="x in list"><td>{{x}}</td></tr>
</table>
</body>
</html>

7.http请求

<!DOCTYPE html>
<html>
<head><title>angularJS入门小demo08-内置服务$http</title><script src="angular.min.js"></script><script>// 建立模块var app = angular.module("myApp",[]);// 创建控制器 $scope就是控制层与视图层之间交换数据的桥梁app.controller("myController",function($scope,$http){$scope.findList = function () {$http.get("data.json").success(function (response) {$scope.list = response;});}});</script>
</head>
<body ng-app="myApp" ng-controller="myController" ng-init="findList()"><table><tr><td>姓名</td><td>数学</td><td>语文</td></tr><tr ng-repeat="entity in list"><td>{{entity.name}}</td><td>{{entity.shuxue}}</td><td>{{entity.yuwen}}</td></tr>
</table>
</body>
</html>

2. 代码

1. 未分页

brand.html

 <script src="../plugins/angularjs/angular.min.js"></script><script type="text/javascript">var app = angular.module('pinyougou',[]);app.controller('brandController',function ($scope, $http) {// 查询品牌列表$scope.findAll = function () {$http.get('../brand/findAll.do').success(function (response) {$scope.list = response;});}});</script>
<body class="hold-transition skin-red sidebar-mini" ng-app="pinyougou" ng-controller="brandController" ng-init="findAll()">...<tbody><tr ng-repeat="entity in list"><td><input  type="checkbox" ></td>                                       <td>{{entity.id}}</td><td>{{entity.name}}</td><td>{{entity.firstChar}}</td><td class="text-center">                                           <button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal"  >修改</button>                                          </td></tr></tbody>

2. 分页

品牌分页:

前端给后端:当前页,每页记录数;

后端给前端:总记录数,当前页记录。

思路:

后端应该显示什么格式呢?

json,总记录数,当前页记录

{total:100,rows:[]}

方法1 :

Map map = new HashMap();
map.put('total',100);
map.put('rows',list);
return map;

方法2:

创建类,包含total和rows属性

1. 实体类

和具体业务无关,entity

public class PageResult implements Serializable {private Long total;//总记录数private List rows;// 当前页结果public PageResult(Long total, List rows) {this.total = total;this.rows = rows;}
//get set方法

2. 品牌分页的接口

public interface BrandService {PageResult findPage(int pageNum,int pageSize);
}

3. 实现类

用到了pageHelper插件

@Service
public class BrandServiceImpl implements BrandService {@Overridepublic PageResult findPage(int pageNum, int pageSize) {PageHelper.startPage(pageNum,pageSize);Page<TbBrand> page = (Page<TbBrand>) brandMapper.selectByExample(null);// 封装到PageResult中return new PageResult(page.getTotal(),page.getResult());}
}

4. 商家controller

@RestController
@RequestMapping("/brand")
public class BrandController {@RequestMapping("/findPage")public PageResult findPage(int page,int size){return brandService.findPage(page,size);}
}

5. 分页的前端实现

在body的table下边数据列表部分增加一行

<!--数据列表/-->
<tm-pagination conf="paginationConf"></tm-pagination>

head里引入分页的js和css

<!--分页组件开始-->
<script src="../plugins/angularjs/pagination.js"></script>
<link rel="stylesheet" href="../plugins/angularjs/pagination.css">
<!--分页组件结束-->

在script里增加分页的功能

<script type="text/javascript">var app = angular.module('pinyougou',['pagination']);app.controller('brandController',function ($scope, $http) {// 查询品牌列表$scope.findAll = function () {$http.get('../brand/findAll.do').success(function (response) {$scope.list = response;});}// 分页控件配置 currentPage当前页 totalItems 总记录数 itemsPerPage 每页记录数// perPageOptions分页选项  onChange 当页码变更后自动触发的方法$scope.paginationConf = {currentPage:1,totalItems:10,itemsPerPage:10,perPageOptions:[10,20,30,40,50],onChange:function () {$scope.reloadList();}};// 刷新列表,之后会复用,提取为方法$scope.reloadList = function(){$scope.findPage($scope.paginationConf.currentPage, $scope.paginationConf.itemsPerPage);};$scope.findPage = function (page, size) {$http.get('../brand/findPage.do?page='+page+'&size='+size).success(function (response) {$scope.list = response.rows;//显示当前页数据$scope.paginationConf.totalItems = response.total;//更新总记录数})}});</script>

6. 品牌新增

1. 新建实体类

用于封装向前端返回的结果,成功与否。

public class Result implements Serializable {private boolean success; // 成功与否private String message; // 传输的具体信息public Result(boolean success, String message) {this.success = success;this.message = message;}
// ...
2. 接口
public interface BrandService {// 增加品牌void addBrand(TbBrand brand);
}
3. 实现类
@Service
public class BrandServiceImpl implements BrandService {@Overridepublic void addBrand(TbBrand brand) {brandMapper.insert(brand);}
}
4. 商家的controller
    @RequestMapping("/add")public Result addBrand(@RequestBody TbBrand brand){try {brandService.addBrand(brand);return new Result(true,"增加品牌成功");} catch (Exception e) {e.printStackTrace();return new Result(false,"增加品牌失败");}}
5. 前端

方法

// 新增品牌
$scope.add = function () {$http.post('../brand/add.do',$scope.entity).success(function (response) {if(response.success){$scope.reloadList();// 刷新}else{alert(response.message);}});
}

body的编辑窗口

<tr><td>品牌名称</td><td><input  class="form-control" placeholder="品牌名称" ng-model="entity.name">  </td>
</tr>
<tr><td>首字母</td><td><input  class="form-control" placeholder="首字母" ng-model="entity.firstChar">  </td>// 保存按钮<button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="add()">保存</button>

小瑕疵:每次新建都能看到前一次,不爽,如何修改?

修改新建按钮

<button type="button" class="btn btn-default" title="新建" data-toggle="modal" data-target="#editModal" ng-click="entity={}"><i class="fa fa-file-o" ></i> 新建</button>

7. 品牌修改

其实分两步:根据id查找和更新

1. 接口
    // 根据id查询TbBrand findOne(Long id);// 更新品牌void updateBrand(TbBrand brand);
2. 实现类
     @Overridepublic TbBrand findOne(Long id) {return brandMapper.selectByPrimaryKey(id);}@Overridepublic void updateBrand(TbBrand brand) {brandMapper.updateByPrimaryKey(brand);}
3. 商家的controller
    @RequestMapping("/findOne")public TbBrand findOne(Long id){return brandService.findOne(id);}@RequestMapping("/update")public Result updateBrand(@RequestBody TbBrand brand){try {brandService.updateBrand(brand);return new Result(true,"品牌更新成功");} catch (Exception e) {e.printStackTrace();return new Result(false,"品牌更新失败");}}
4. 前端

点击修改按钮,弹出的框和增加的框一样,然后修改,然后保存

<button type="button" class="btn bg-olive btn-xs" data-toggle="modal" data-target="#editModal" ng-click="findOne(entity.id)" >修改</button>

方法

// 根据id查询品牌
$scope.findOne = function (id) {$http.get('../brand/findOne.do?id='+id).success(function (response) {$scope.entity = response;});
};

编辑窗口的保存

<button class="btn btn-success" data-dismiss="modal" aria-hidden="true" ng-click="save()">保存</button>

方法

借用add方法

$scope.save = function () {var methodName = 'add'; //方法名if($scope.entity.id!=null){methodName = 'update';}$http.post('../brand/'+methodName+'.do',$scope.entity).success(function (response) {if(response.success){$scope.reloadList();// 刷新}else{alert(response.message);}});}

8. 删除品牌

本项目采用复式删除,通过复选框删除

1. 接口
// 批量删除品牌void deleteBrands(Long[] ids);
2. 实现类
@Overridepublic void deleteBrands(Long[] ids) {for (Long id : ids) {brandMapper.deleteByPrimaryKey(id);}}
3. 商家的controller
 @RequestMapping("/delete")public Result deleteBrands(Long[] ids){try {brandService.deleteBrands(ids);return new Result(true,"品牌删除成功");} catch (Exception e) {e.printStackTrace();return new Result(false,"品牌删除失败");}}
4. 前端

需要定义一个集合存储勾选的复选框的id

方法

包含push添加,js原生的indexOf和splice

$scope.selectIds = [];// 用户勾选的ID集合$scope.updateSelection = function ($event,id) {if($event.target.checked){$scope.selectIds.push(id);//push向集合中添加元素}else{// 删除元素var index = $scope.selectIds.indexOf(id);//查找值的位置$scope.selectIds.splice(index,1);// 参数1:值的位置 参数2:移除的个数}
}

body

<td><input  type="checkbox" ng-click="updateSelection($event,entity.id)"></td>
<td>{{entity.id}}</td>
<td>{{entity.name}}</td>
<td>{{entity.firstChar}}</td>

最好在后边添加个{{selectIds}}

删除

// 删除$scope.deleteSelection = function () {$http.get('../brand/delete.do?ids='+$scope.selectIds).success(function (response) {if(response.success){$scope.reloadList();//刷新}else{alert(response.message);}});}

body

<button type="button" class="btn btn-default" title="删除" ng-click="deleteSelection()"><i class="fa fa-trash-o"></i> 删除</button>

9.条件查询

其实跟分页查询所有一样,只是

TODO 后端碰到问题,未解决!

后端问题为:invalid constant type,修改依赖的javassist版本即可。

1. 接口
    // 条件查询PageResult findPage(TbBrand brand, int pageNum,int pageSize);
2. 实现类
@Overridepublic PageResult findPage(TbBrand brand, int pageNum, int pageSize) {PageHelper.startPage(pageNum,pageSize);TbBrandExample example = new TbBrandExample();Criteria criteria = example.createCriteria();if(brand!=null){if(brand.getName()!=null && brand.getName().length()>0){criteria.andNameLike("%"+brand.getName()+"%");}if(brand.getFirstChar()!=null && brand.getFirstChar().length()>0){criteria.andFirstCharLike("%"+brand.getFirstChar()+"%");}}Page<TbBrand> page = (Page<TbBrand>) brandMapper.selectByExample(example);// 封装到PageResult中return new PageResult(page.getTotal(),page.getResult());}
3. controller
@RequestMapping("/search")public PageResult search(@RequestBody TbBrand brand,int page,int size){return brandService.findPage(brand,page,size);}
4. 前端

需要增加搜索框

<div class="box-tools pull-right"><div class="has-feedback">品牌名称:<input ng-model="searchEntity.name"> 品牌首字母:<input ng-model="searchEntity.firstChar">  <button class="btn btn-default" ng-click="reloadList()">查询</button></div>

方法

$scope.searchEntity={};
// 条件查询
$scope.search = function (page,size) {// 混合提交$http.post('../brand/search.do?page='+page+'&size='+size,$scope.searchEntity).success(function (response) {$scope.list = response.rows;//显示当前页数据$scope.paginationConf.totalItems = response.total;//更新总记录数});
};

修改reload

// 刷新列表
$scope.reloadList = function(){$scope.search($scope.paginationConf.currentPage,$scope.paginationConf.itemsPerPage);
};

练手项目1笔记 day02AnglaJS相关推荐

  1. 练手项目2笔记之day01

    文章目录 学习目标 1. 项目的功能架构 1. 项目背景 2. 功能模块 3. 项目原型 2. 项目的技术架构 1. 技术架构 2. 技术栈 3. 开发步骤 3. CMS需求分析 1. 什么是CMS ...

  2. 适合新手入门的8个python项目_推荐:一个适合于Python新手的入门练手项目

    随着人工智能的兴起,国内掀起了一股Python学习热潮,入门级编程语言,大多选择Python,有经验的程序员,也开始学习Python,正所谓是人生苦短,我用Python 有个Python入门练手项目, ...

  3. php练手项目20个,2022最新版 附源码

    博主今天分享几个平时收集整理的php实战练手项目,都是一些适合php新手练习的小项目合集,希望对大家有用. 1.[从0到1构建b2b电商服务系统] 2.[实战项目之仿淘宝网] 3.[手把手带你开发一个 ...

  4. 【C语言】游戏开发:天天酷跑丨完美练手项目 [附源码]

    目录 一.项目说明: 二.项目作用 三.项目技术要求 四.库.宏.主函数说明 五.项目实现 5.1游戏背景的实现 5.2实现Hero奔跑 5.3 实现Hero跳跃 5.4 优化帧等待 5.6使用结构体 ...

  5. 70个Python练手项目列表 预祝大家 快乐

    小孩眺望远方,成人怀念故乡. 为此给大家分享一下珍藏的Python实战项目,祝大家节日快乐哦!!! Python 前言:不管学习哪门语言都希望能做出实际的东西来,这个实际的东西当然就是项目啦,不用多说 ...

  6. 一个适合于Python 初学者的入门练手项目

    随着人工智能的兴起,国内掀起了一股Python学习热潮,入门级编程语言,大多选择Python,有经验的程序员,也开始学习Python,正所谓是人生苦短,我用Python 有个Python入门练手项目, ...

  7. 推荐 Python 十大经典练手项目,让你的 Python 技能点全亮!

    前言:如果有人问:"Python还火吗?""当然,很火.""哪能火多久呢?""不知道." 技术发展到现在衍生出许多种编程 ...

  8. 别让双手闲下来,来做一些练手项目吧

    作者:Weston,原文链接,原文日期:2016-01-27 译者:saitjr:校对:Cee:定稿:千叶知风 自从我昨天发了文,收到的最多的评论就是: 我应该选择哪些 App 来练手呢? 这个问题很 ...

  9. python项目-推荐 10 个有趣的 Python 练手项目

    想成为一个优秀的Python程序员,没有捷径可走,势必要花费大量时间在键盘后. 而不断地进行各种小项目开发,可以为之后的大开发项目积攒经验,做好准备. 但不少人都在为开发什么项目而苦恼. 因此,我为大 ...

最新文章

  1. Ubuntu中安装sqldeveloper出现的问题及其解决方法
  2. 用 HTTPS 就安全了?HTTPS 会被抓包吗?
  3. 笔记本电脑摄像头不能用_苹果笔记本电脑风扇狂转不停,卡慢不能用,是这小东西坏了...
  4. 做柜员还是程序员_应届生放弃互联网大厂回家乡银行:程序员五万比不上柜员五千...
  5. 基于TCP的网络编程
  6. python中unique函数_Pandas Series.unique()用法介绍
  7. 毕设系列之 -- 基于大数据的全国热门旅游景点数据分析与可视化
  8. iOS定位获取城市名
  9. wps在线预览接口_Office在线预览及PDF在线预览的实现方式大集合
  10. 如何利用cyclone对SPC560离线烧写
  11. 在cmd的命令下 用Mysql中建立一个表
  12. 深度学习框架tensorflow学习与应用——代码笔记11(未完成)
  13. 【微信支付】Java实现微信APP支付流程
  14. 移动应用测试---安居客
  15. R语言学习笔记(概念、公式及R函数)
  16. Java架构师视频+授课资料
  17. 批量修改.CR2 格式的照片为.jpg
  18. React新生命周期--getDerivedStateFromProps、getSnapshotBeforeUpdate
  19. 【Esp32】用esp32和max30102制作一个血氧仪
  20. 解决 无法解析名称 NaiveBayes.fit。/i get Undefined variable “NaiveBayes“ or class “NaiveBayes.fit“.

热门文章

  1. 为什么很多人都知道打工不挣钱却还在打工?
  2. 校园兼职平台(合作重构版)
  3. 题目:判断字符串是否对称
  4. python中字符串比较是基于字典序的_Python字符串字典集合
  5. Polysh使用简介
  6. Azkaban 环境搭建及executor became inactive问题
  7. 可编程直流电源的特点都有哪些呢?
  8. 什么是phpize及其用法
  9. 【项目】实现网页搜索框功能
  10. uname命令 linux,Linux系统下使用uname命令显示系统和硬件信息