今天我们来继续丰富上次的例子。我们来搞些 稍微复杂点的应用。

首先我们来加一个全选 的功能。

上一篇的例子里我们看到 分页时载入的是我们通过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的结合使用 (二)的更多相关文章

  1. 如何使用angularjs实现ajax异步请求

    Sample.html <!DOCTYPE html> <html ng-app="myApp"> <head> <title>fo ...

  2. angularjs和ajax的结合使用 (一)

    好久没写文了.这是一篇关于easyui配合ajax使用 的文章, 顺带介绍angularjs的使用 以及让你感受到angularjs的威力.网上对于ajax 的文也是多如牛毛 .我就不直接 从那种原生 ...

  3. angularjs + seajs构建Web Form前端(二)

    回顾 上一篇讲解了引入bootstrap构建一个简单的登录页面,如何让angularjs自动启动并绑定视图,操作过程当中如何使用ui-bootstrap,继而完成简单功能后如何引入seajs后如何使n ...

  4. ajax向前台输出二维数组 并解析

    最近在弄一个售后数据统计的功能,里边需要统计特定时期内各种客户.机型的分布比例,单单table来计算并显示很死板(一点也不酷) 于是决定用jquery插件flot并通过ajax传输数据 :flot的折 ...

  5. angularJS项目-ajax事件的按钮loading和页面loading状态 & Controller之间通信-待续

    1).按钮loading --TODO 2). page loading状态 1.在module中注入指令 // Route State Load Spinner(used on page or co ...

  6. Ajax的进阶学习(二)

    JSON和JSONP 如果在同一个域下,$.ajax()方法只要设置dataType属性即可加载JSON文件.而在非同域下,可以使用JSONP,但也是有条件的. Ajax进阶.html: <!D ...

  7. jQuery基础---Ajax基础教程(二)

    jQuery基础---Ajax进阶 内容提纲: 1.加载请求 2.错误处理 3.请求全局事件 4.JSON 和 JSONP 5.jqXHR 对象 发文不易,转载请注明出处! 在 Ajax 基础一篇中, ...

  8. Ajax基础知识(二)

    接上一篇  Ajax基础知识(一) 在上一篇博客里,抛弃了VS中新建aspx页面,拖个button写上C#代码的方式.使用ajax的方式,异步向服务器请求数据.我们让服务器只简单的返回一个" ...

  9. angularjs和ajax的结合使用 (三)

    转眼九月份了,忙忙碌碌 发现今年还没开过张,写一篇吧. 15年在空闲时就倒腾过angularjs那玩意儿 ,觉得还是挺好的,李金龙那厚厚的一本书,只不过没有系统化应用.最主要的是原来有一个东西没有用到 ...

随机推荐

  1. await and async

    Most people have already heard about the new “async” and “await” functionality coming in Visual Stud ...

  2. javascript动画系列第一篇——模拟拖拽

    × 目录 [1]原理介绍 [2]代码实现 [3]代码优化[4]拖拽冲突[5]IE兼容 前面的话 从本文开始,介绍javascript动画系列.javascript本身是具有原生拖放功能的,但是由于兼容 ...

  3. 缓存工具类CacheHelper

    代码: using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst ...

  4. prometheus监控系统

    关于Prometheus Prometheus是一套开源的监控系统,它将所有信息都存储为时间序列数据:因此实现一种Profiling监控方式,实时分析系统运行的状态.执行时间.调用次数等,以找到系统的 ...

  5. 如何理解DT将是未来IT的转型之路?

    如今的IT面临着内忧外患的挑战. 一方面,企业多多少少都建立了信息化,有些企业或集团甚至会有数几十个分公司,包含直销.代理.零售以及第三方物流等多种业态.越是复杂的业务,信息化建设越困难,比如运用大量 ...

  6. 【SAP业务模式】之ICS(七):IDOC配置

    这是ICS业务模式系列的最后一篇了,主要讲解IDOC的配置. 一.指定EDI传输的供应商逻辑地址 事务代码:WEL1 注意:上面逻辑地址是生产公司+内部客户.有以下两种情形: 1.如果内部客户都是纯数 ...

  7. Java虚拟机 JVM

    finalize();(不建议使用,代价高,不确定性大) 如果你在一个类中覆写了finalize()方法, 那么你可以在第一次被GC的时候,挽救一个你想挽救的对象,让其不被回收,但只能挽救一次. GC ...

  8. HTML5 标签 details 展开 搜索

    details有一个新增加的子标签--summary,当鼠标点击summary标签中的内容文字时,details标签中的其他所有元素将会展开或收缩. 默认状态为 收缩状态 设置为展开状态为 <d ...

  9. BZOJ 1146: [CTSC2008]网络管理Network [树上带修改主席树]

    1146: [CTSC2008]网络管理Network Time Limit: 50 Sec  Memory Limit: 162 MBSubmit: 3522  Solved: 1041[Submi ...

  10. Ubuntu(Linux) + mono + jexus +asp.net MVC3 部署

    感谢  张善友 的建议,我把 微信订餐  由nginx 改成 jexus,目前运行状况来说,确实稳定了很多,再次感谢. 部署步骤参考 jexus官网:http://www.jexus.org/ htt ...