今天我们来继续丰富上次的例子。我们来搞些 稍微复杂点的应用。
首先我们来加一个全选 的功能。
上一篇的例子里我们看到 分页时载入的是我们通过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 。
我们做这个功能正是利用了上述原理。
表格头部加个 全选功能的复选框
1 <th> 2 <input id="Checkbox1" ng-click="selectAll($event)" type="checkbox" />全选 3 4 </th>
都知道在javascript里面 调用函数时 要把当前单击的控件对象传进去 使用this ,angularjs 里面不一样 使用$event 。那么对应的功能函数又是怎样的呢
1 //全选 2 $scope.selectAll = function (sender) { 3 if ($(sender.target).is(':checked')) { 4 for (var i = 0; i < $scope.data.length; i++) { 5 $scope.data[i].chk = true; 6 } 7 } 8 else { 9 for (var i = 0; i < $scope.data.length; i++) { 10 $scope.data[i].chk = false; 11 } 12 } 13 }
然后再行循环里面 弄个复选框的双向绑定就可以了
1 <td> 2 <input ng-checked="{{stu.chk}}" ng-model="stu.chk" type="checkbox" /></td>
看 就可以了 虽然我们回传的数据多了个chk属性 但是依然能够被成功解析成StudentsInfo对象。angularjs里面非常看重数据操作跟界面上的对应关系 让你的程序更加面向对象化。
接下来我们来说下一些常用的数据格式化方式。angularjs里面自带了一些自带的filter 可提供格式化日期 这些 {{ stu.createDate | date: 'yyyy年MM月dd' }}
找了下没找到格式化布尔值的方式。还自己写了个filter:
1 app.filter('odditems', function () { 2 return function (inputArray) { 3 if (inputArray == true) 4 return '是'; 5 else if (inputArray == false) 6 return '否'; 7 else 8 return '空'; 9 } 10 });
后来证明完全是我多虑了 ,原来angularjs的表达式 也支持三元运算 :{{stu.isChecked==true?'yes':''}}
接下来继续扩展上面的例子 来加个复选项的功能
最常见的那种就是爱好 你有神马爱好 打篮球 羽毛球 游泳 ,哇哈哈 , 别打我。这是一个多对多的关系 可能会想到专门建一个表来存储这些东西 ,用不着啦 。直接加个文本字段 以逗号隔开就可以了。
先展示一个网上的一个复选功能的例子:
1 <body ng-app="app"> 2 <div ng-controller="MainCtrl" class="container bg-color"> 3 <section> 4 <pre>{{choseArr}}</pre> 5 全选: <input type="checkbox" ng-model="master" ng-click="all(master,tesarry)"> 6 <div ng-repeat="z in tesarry"> 7 <input id={{z}} type="checkbox" ng-model="x" ng-checked="master" ng-click="chk(z,x)">{{z}} 8 </div> 9 <a href="#" class="btn btn-danger" ng-click="delete()"> 删除</a> 10 </section> 11 </div> 12 <script> 13 var app = angular.module('app', []); 14 app.controller('MainCtrl', function ($scope, $http, $timeout) { 15 $scope.tesarry = ['1', '2', '3', '4', '5'];//初始化数据 16 $scope.choseArr = [];//定义数组用于存放前端显示 17 var str = "";// 18 var len = $scope.tesarry.length;//初始化数据長度 19 var flag = '';//是否点击了全选,是为a 20 $scope.x = false;//默认未选中 21 22 $scope.all = function (c, v) {//全选 23 if (c == true) { 24 $scope.x = true; 25 $scope.choseArr = angular.copy(v); 26 flag = 'a'; 27 } else { 28 $scope.x = false; 29 $scope.choseArr = []; 30 flag = 'b'; 31 } 32 }; 33 $scope.chk = function (z, x) {//单选或者多选 34 if (flag == 'a') {//在全选的基础上操作 35 str = $scope.choseArr.join(',') + ','; 36 } 37 if (x == true) {//选中 38 str = str + z + ','; 39 flag = 'c' 40 if ($scope.choseArr.length == len - 1) { 41 $scope.master = true 42 } 43 } else { 44 str = str.replace(z + ',', '');//取消选中 45 } 46 47 $scope.choseArr = (str.substr(0, str.length - 1)).split(','); 48 var dex = $scope.choseArr.indexOf("");//判断数组中有没有"",有的话返回值大于等于0,没有返回-1 49 if (dex >= 0) { 50 $scope.choseArr.splice(dex, 1);//删除数组中的""; 51 }; 52 if ($scope.choseArr.length == 0) { $scope.master = false }; 53 }; 54 $scope.delete = function () {// 操作CURD 55 if ($scope.choseArr[0] == "" || $scope.choseArr.length == 0) {//没有选择一个的时候提示 56 alert("请至少选中一条数据在操作!") 57 return; 58 }; 59 for (var i = 0; i < $scope.choseArr.length; i++) { 60 alert($scope.choseArr[i]); 61 console.log($scope.choseArr[i]);//遍历选中的id 62 } 63 };//delete end 64 }); 65 </script> 66 67 </body>