angularjs和ajax的结合使用 (二)
今天我们来继续丰富上次的例子。我们来搞些 稍微复杂点的应用。
首先我们来加一个全选 的功能。
上一篇的例子里我们看到 分页时载入的是我们通过linq 查询自定义列 然后构建的匿名类 。使用这种EF框架+linq 查询的方式 我认为不方便的一点就是 要不你就只能select 一个固定对应表的数据模型类名 ,但是序列化成json的时候对外键类引用有天然的bug ,就是框架自动序列化成json格式时会出循环引用错误 。序列化类型为XX的对象时检测到循环引用。没办法 我们能做的就是屏蔽某些属性 。方式就是在字段属性上方加上[AjaxPro.AjaxNonSerializable] 光这样还不行 如果 字段属性 有 virtual 关键字 还会报错,但是EF写数据模型代码的时候 外键属性如果不加virtual 修饰 就等于废的 外键抓不过来的。真是令人蛋疼的问题。大多数情况我们查询都不会只查询单一表的数据 并且基本还是用匿名类的方式 想用什么字段用什么字段 外键也可以及时查询出来 。综合上面的问题 还是用匿名类的方式 。
如果你希望客户端传回来的数据对象 自动序列化成你的C#数据模型类 。也有些需要注意的地方 除了上面我说的 ,还有:
1不能用Ilist 直接使用List 数组没试过 好像也不行 。
2为了你传到客户端的json数据 又能够无缝的传回来。 在使用匿名类linq方式查询的时候 如果你想从客户端自动序列化成你C#数据模型类的属性 那么你就把匿名查询时的字段名称写成一样。
3字段并不一定要一一完整对应 框架会检查你服务端接收参数的数据模型类有哪些字段 然后从返回的json数据里找 不符合的字段 他不会管的 并且也不会报错 只找json数据里符合的字段 然后序列化成 你c#数据模型类 这点我认为框架处理的非常好 非常智能。比如上面全选 的功能 我就给表格上绑的数据多加了一列 列名为chk 类型为bool 为true 则选中 没有这个字段 或者为false 都为没选中,
4并且javascript这个很烂的东西 有个好处就是 变量可以灵活的使用 无类型限制。比如可以随意定义json格式的数据var person={name:"xiang"} 定义完过后 可以继续在其基础上添加内容 像这样 person.chk=true 。
我们做这个功能正是利用了上述原理。
表格头部加个 全选功能的复选框
<th>
<input id="Checkbox1" ng-click="selectAll($event)" type="checkbox" />全选 </th>
都知道在javascript里面 调用函数时 要把当前单击的控件对象传进去 使用this ,angularjs 里面不一样 使用$event 。那么对应的功能函数又是怎样的呢
//全选
$scope.selectAll = function (sender) {
if ($(sender.target).is(':checked')) {
for (var i = 0; i < $scope.data.length; i++) {
$scope.data[i].chk = true;
}
}
else {
for (var i = 0; i < $scope.data.length; i++) {
$scope.data[i].chk = false;
}
}
}
然后再行循环里面 弄个复选框的双向绑定就可以了
<td>
<input ng-checked="{{stu.chk}}" ng-model="stu.chk" type="checkbox" /></td>
看 就可以了 虽然我们回传的数据多了个chk属性 但是依然能够被成功解析成StudentsInfo对象。angularjs里面非常看重数据操作跟界面上的对应关系 让你的程序更加面向对象化。
接下来我们来说下一些常用的数据格式化方式。angularjs里面自带了一些自带的filter 可提供格式化日期 这些 {{ stu.createDate | date: 'yyyy年MM月dd' }}
找了下没找到格式化布尔值的方式。还自己写了个filter:
app.filter('odditems', function () {
return function (inputArray) {
if (inputArray == true)
return '是';
else if (inputArray == false)
return '否';
else
return '空';
}
});
后来证明完全是我多虑了 ,原来angularjs的表达式 也支持三元运算 :{{stu.isChecked==true?'yes':''}}
接下来继续扩展上面的例子 来加个复选项的功能
最常见的那种就是爱好 你有神马爱好 打篮球 羽毛球 游泳 ,哇哈哈 , 别打我。这是一个多对多的关系 可能会想到专门建一个表来存储这些东西 ,用不着啦 。直接加个文本字段 以逗号隔开就可以了。
先展示一个网上的一个复选功能的例子:
<body ng-app="app">
<div ng-controller="MainCtrl" class="container bg-color">
<section>
<pre>{{choseArr}}</pre>
全选: <input type="checkbox" ng-model="master" ng-click="all(master,tesarry)">
<div ng-repeat="z in tesarry">
<input id={{z}} type="checkbox" ng-model="x" ng-checked="master" ng-click="chk(z,x)">{{z}}
</div>
<a href="#" class="btn btn-danger" ng-click="delete()"> 删除</a>
</section>
</div>
<script>
var app = angular.module('app', []);
app.controller('MainCtrl', function ($scope, $http, $timeout) {
$scope.tesarry = ['1', '2', '3', '4', '5'];//初始化数据
$scope.choseArr = [];//定义数组用于存放前端显示
var str = "";//
var len = $scope.tesarry.length;//初始化数据長度
var flag = '';//是否点击了全选,是为a
$scope.x = false;//默认未选中 $scope.all = function (c, v) {//全选
if (c == true) {
$scope.x = true;
$scope.choseArr = angular.copy(v);
flag = 'a';
} else {
$scope.x = false;
$scope.choseArr = [];
flag = 'b';
}
};
$scope.chk = function (z, x) {//单选或者多选
if (flag == 'a') {//在全选的基础上操作
str = $scope.choseArr.join(',') + ',';
}
if (x == true) {//选中
str = str + z + ',';
flag = 'c'
if ($scope.choseArr.length == len - 1) {
$scope.master = true
}
} else {
str = str.replace(z + ',', '');//取消选中
} $scope.choseArr = (str.substr(0, str.length - 1)).split(',');
var dex = $scope.choseArr.indexOf("");//判断数组中有没有"",有的话返回值大于等于0,没有返回-1
if (dex >= 0) {
$scope.choseArr.splice(dex, 1);//删除数组中的"";
};
if ($scope.choseArr.length == 0) { $scope.master = false };
};
$scope.delete = function () {// 操作CURD
if ($scope.choseArr[0] == "" || $scope.choseArr.length == 0) {//没有选择一个的时候提示
alert("请至少选中一条数据在操作!")
return;
};
for (var i = 0; i < $scope.choseArr.length; i++) {
alert($scope.choseArr[i]);
console.log($scope.choseArr[i]);//遍历选中的id
}
};//delete end
});
</script> </body>
我也不想多说 ,又叫变量又加这样那样处理的 。麻烦 复杂。我还不如直接用jquery呢。angularjs一直的理念就是 只关注数据模型。
其实你需要的是这样一种格式的东西:
$scope.ar = [{ id: 1, name: "basketball", st: true }, { id: 2, name: "tennis", st: false }, { id: 3, name: "swimming", st: true }];
st代表选中与否 id代表复选项的value值 name代表复选项的text值 然后用repeat一循环 是不是这样 是不是应该这样:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>多选</title>
<script type="text/javascript" src="../jquery-easyui-1.4.3/jquery.min.js"></script>
<script type="text/javascript" src="../angularJs/angular.js"></script>
<script>
function myCtr($scope) {
//实现多选 看了网上的一个 又是弄中间变量 又是操作dom
//no 数据 组织方式 这才是angular way ,根本不需要那么多操作 只需要操作数据 你只需要操作数据 看简简单单 清清爽爽
//按说的话这种需求是比较少的 如果设计功能的时候 你非要整这么个 那么没办法 数据结构就是这样 你就得这么做 别想偷懒
//你必须得形成这样一种数据结构了 交给前端
$scope.ar = [{ id: 1, name: "basketball", st: true }, { id: 2, name: "tennis", st: false }, { id: 3, name: "swimming", st: true }];
$scope.ar2 = [2, 3];
$scope.exist = function (id) {
for (var i = 0; i < $scope.ar2.length ; i++) {
if ($scope.ar2[i] == id)
return true;
}
return false;
}
$scope.show = function () {
var rst = "";
for (var i = 0; i < $scope.ar.length ; i++) {
if ($scope.ar[i].st == true)
rst += $scope.ar[i].name + ',';
}
alert(rst);
}
}
</script>
</head>
<body ng-app ng-controller="myCtr">
<ul>
<li ng-repeat="z in ar">
<input id="chk{{z.id}}" ng-checked="{{z.st}}" ng-model="z.st" type="checkbox" />
<label for="chk{{z.id}}">{{z.name}}</label>
</li>
</ul>
<hr />
<ul >
<li ng-repeat="z in ar">
<input id="chkk{{z.id}}" ng-checked="exist(z.id)" ng-model="z.st" type="checkbox" />
<label for="chkk{{z.id}}">{{z.name}}</label>
</li>
</ul> <input id="Button1" type="button" ng-click="show()" value="show" /> </body>
</html>
为了得到上述那种格式的数据 本来在服务端编写这样的代码 以属性的方式呈现:
public List<CheckboxItem> favorsValue
{
get
{
if(_favorsValue!=null)
return _favorsValue;
else if (string.IsNullOrEmpty(favors)==false)
{
Dal d = new Dal();
List<CheckboxItem> flist = d.GetAllFavors();
string[] curlist = favors.Split(',');
for (int i = ; i < flist.Count; i++)
{
for (int j = ; j < curlist.Length; j++)
{
if (flist[i].id == curlist[j])
{
flist[i].Checked = true;
continue;
}
}
}
return flist;
//return favors.Split(',');
}
else
{
Dal d = new Dal();
List<CheckboxItem> flist = d.GetAllFavors();
return flist;
}
}
set {
_favorsValue = value;
} }
比如我们有三种不同的爱好 那么把从数据库里都出来 ,然后根据每条数据各自不同的以逗号隔开的字符 转换成
$scope.ar = [{ id: 1, name: "basketball", st: true }, { id: 2, name: "tennis", st: false }, { id: 3, name: "swimming", st: true }];
这样的数据 。然后前端得到的自动就是这种格式的数据了 操作后又跟后端做到无缝衔接。想法是好的总会遇到各种问题 这种属性逻辑代码必须写在对应的数据模型代码里 给linq查询带来了限制。 如果使用匿名类的方式做linq查询又调用不了这个逻辑 匿名类是调用不了逻辑代码的 只能够做简单的初始化属性的工作 。为了在匿名类里调用方法我都找疯了 结果还是没找到,最后还是妥协了 把这个工作放到客户端去处理。
//多选框绑定
$scope.transFav = function () {
if ($scope.curobj.favorsValue != null && $scope.curobj.favorsValue != undefined)
return;
if ($scope.curobj.favors) { var d = [{ id: "1", name: "basketball", Checked: false }, { id: "2", name: "tennis", Checked: false }, { id: "3", name: "swimming", Checked: false }];
var curlist = $scope.curobj.favors.split(",");
for (var i = 0; i < d.length; i++) {
for (var j = 0; j < curlist.length; j++) {
if (d[i].id == curlist[j]) {
d[i].Checked = true;
continue;
}
}
}
$scope.curobj.favorsValue = d;
}
else {
var d = [{ id: "1", name: "basketball", Checked: false }, { id: "2", name: "tennis", Checked: false }, { id: "3", name: "swimming", Checked: false }];
$scope.curobj.favorsValue = d;
}
}
但是在服务端属性我们还是公开这么一个属性 public List<CheckboxItem> favorsValue{ get; set; } 让客户端更改数据后回传可以做到无缝衔接。客户端数据绑定:
<ul>
<li ng-repeat="z in curobj.favorsValue">
<input id="chkk{{z.id}}" ng-checked="z.Checked" value="{{z.id}}" name="favorchk" ng-model="z.Checked" type="checkbox" />
<label for="chkk{{z.id}}">{{z.name}}</label>
</li>
</ul>
客户端改变favorsValue的内容服务端可获知 然后重新组织成逗号隔开的字符串。当然这个工作你在客户端做也是可以的:
//根据name 获得所有checkbox选取的的值
function addMem(names) {
var allNames = "";
$("input[name='" + names + "']").each(function () {
if ($(this).attr("checked") == "checked") {
if (allNames == "") {
allNames = $(this).attr("value");
} else {
allNames += "," + $(this).attr("value");
}
}
});
//alert(allNames);
return allNames;
}
运行效果:
源码文件还是基于上一篇更改,直接下载上一篇的源码即可。
angularjs和ajax的结合使用 (二)的更多相关文章
- 如何使用angularjs实现ajax异步请求
Sample.html <!DOCTYPE html> <html ng-app="myApp"> <head> <title>fo ...
- angularjs和ajax的结合使用 (一)
好久没写文了.这是一篇关于easyui配合ajax使用 的文章, 顺带介绍angularjs的使用 以及让你感受到angularjs的威力.网上对于ajax 的文也是多如牛毛 .我就不直接 从那种原生 ...
- angularjs + seajs构建Web Form前端(二)
回顾 上一篇讲解了引入bootstrap构建一个简单的登录页面,如何让angularjs自动启动并绑定视图,操作过程当中如何使用ui-bootstrap,继而完成简单功能后如何引入seajs后如何使n ...
- ajax向前台输出二维数组 并解析
最近在弄一个售后数据统计的功能,里边需要统计特定时期内各种客户.机型的分布比例,单单table来计算并显示很死板(一点也不酷) 于是决定用jquery插件flot并通过ajax传输数据 :flot的折 ...
- angularJS项目-ajax事件的按钮loading和页面loading状态 & Controller之间通信-待续
1).按钮loading --TODO 2). page loading状态 1.在module中注入指令 // Route State Load Spinner(used on page or co ...
- Ajax的进阶学习(二)
JSON和JSONP 如果在同一个域下,$.ajax()方法只要设置dataType属性即可加载JSON文件.而在非同域下,可以使用JSONP,但也是有条件的. Ajax进阶.html: <!D ...
- jQuery基础---Ajax基础教程(二)
jQuery基础---Ajax进阶 内容提纲: 1.加载请求 2.错误处理 3.请求全局事件 4.JSON 和 JSONP 5.jqXHR 对象 发文不易,转载请注明出处! 在 Ajax 基础一篇中, ...
- Ajax基础知识(二)
接上一篇 Ajax基础知识(一) 在上一篇博客里,抛弃了VS中新建aspx页面,拖个button写上C#代码的方式.使用ajax的方式,异步向服务器请求数据.我们让服务器只简单的返回一个" ...
- angularjs和ajax的结合使用 (三)
转眼九月份了,忙忙碌碌 发现今年还没开过张,写一篇吧. 15年在空闲时就倒腾过angularjs那玩意儿 ,觉得还是挺好的,李金龙那厚厚的一本书,只不过没有系统化应用.最主要的是原来有一个东西没有用到 ...
随机推荐
- junit4进行单元测试
一.前言 提供服务的时候,为了保证服务的正确性,有时候需要编写测试类验证其正确性和可用性.以前的做法都是自己简单写一个控制层,然后在控制层里调用服务并测试,这样做虽然能够达到测试的目的,但是太不专业了 ...
- spring boot 部署为jar
前言 一直在ide中敲代码,使用命令行mvn spring-boot:run或者gradlew bootRun来运行spring boot项目.想来放到prod上面也应该很简单.然而今天试了下,各种问 ...
- C#~异步编程再续~await与async引起的w3wp.exe崩溃-问题友好的解决
返回目录 关于死锁的原因 理解该死锁的原因在于理解await 处理contexts的方式,默认的,当一个未完成的Task 被await的时候,当前的上下文将在该Task完成的时候重新获得并继续执行剩余 ...
- javaScript中的小细节-script标签中的预解析
首先介绍预解析,虽然预解析字面意思很好理解,但是却是出坑出的最多的地方,也是bug经常会有的地方,利用好预解析的特性可以解决很多问题,并且提高代码的质量及数量,浏览器在解析代码前会把变量的声明和函数( ...
- BPM生产安全管理解决方案分享
一.方案概述生产安全管理是企业生产管理的重要组成部分,组织实施好企业安全管理规划.指导.检查和决策,保证生产处于最佳安全状态是安全管理的重要内容和职责.H3 BPM企业生产安全管理解决方案是一套专门为 ...
- android计算每个目录剩余空间丶总空间以及SD卡剩余空间
ublic class MemorySpaceCheck { /** * 计算剩余空间 * @param path * @return */ public static String getAvail ...
- atitit.管理学三大定律:彼得原理、墨菲定律、帕金森定律
atitit.管理学三大定律:彼得原理.墨菲定律.帕金森定律 彼得原理(The Peter Principle) 1 彼得原理解决方案1 帕金森定律 2 如何理解墨菲定律2 彼得原理(The Pete ...
- 2003-Can't connect to mysql server on localhost (10061)
mysql数据库出现2003-Can't connect to mysql server on localhost (10061)问题 解决办法:查看wampserver服务器是否启动,如果没有启动启 ...
- Linux设备管理(五)_写自己的sysfs接口
我们在Linux设备管理(一)_kobject, kset,ktype分析一文中介绍了kobject的相关知识,在Linux设备管理(二)_从cdev_add说起和Linux设备管理(三)_总线设备的 ...
- 简单Linux命令学习笔记
1.查看进程 ps -ef | grep 关键字 /*关键字为服务名*/ netstat -unltp | grep 关键字 /*关键字为服务名或者是端口均可*/ 2.杀死进 ...