angularjs 常用功能练习
<!DOCTYPE html> <html ng-app="app"> <head> <meta charset="utf-8"> <title>angularjs练习</title> </head> <body ng-controller="ctrl"> <div> </div> <script src="~/Scripts/angular.min.js"></script> <script> var app=angular.module('app', []); app.controller('ctrl', function ($scope) { }); </script> </body> </html>
单选:
<input type="radio" name="sex" ng-model="sex" value="男" />男 <input type="radio" name="sex" ng-model="sex" value="女" />女 {{sex}}
复选:
<input type="checkbox" ng-model="data.open" ng-true-value="1" ng-false-value="0"/>开 <input type="checkbox" ng-model="data.close" ng-true-value="1" ng-false-value="0" />关
$scope.data = {open:1,close:0};
下拉框:
<select ng-model="user" ng-options="v.age as v.name for v in data"></select> {{user}} $scope.data = [ { name: "张三", age: 12 }, { name: "李四", age: 11 }, { name: "王五", age: 18 }, ] $scope.user = 11;//设定下拉默认值
还可以这样:
<select ng-model="user"> <option value="">请选择</option> <option ng-repeat="v in data" ng-value="{{v.age}}">{{v.name}}</option> </select> {{user}}
如果网页加载速度慢,使用angularjs页面会看到很多”{{}}“,可以通过 ng-cloak 在加载时隐藏:
.......
<style> .ng-cloak { display: none; } </style> </head> <body ng-controller="ctrl" class="ng-cloak">
....
- angular.lowercase:将字符串转换为小写
angular.uppercase:将字符串转换为大写
angular.forEach(obj, iterator, [context]):遍历对象集合,该函数包括三个参数,第一个参数表示需要遍历的对象或数组,第二个参数为一个函数,第三个对象为当前的上下文环境(this);var values = {name: 'misko', gender: 'male'}; var log = []; angular.forEach(values, function(value, key) { this.push(key + ': ' + value); }, log); expect(log).toEqual(['name: misko', 'gender: male']);
angularisUndefinedvalue
- .();判断value是否为一个对象,不包括null
angularisStringvalue - .();判断value是否为Number类型
angularisDatevalue - .();判断value是否为数组
angularisFunctionvalue - .();判断value是否为一个DOM元素,包括JQuery封装的DOM
angular.equals(o1, o2);判断两个对象是否相等
- o1===o2 返回true
- o1和o2的所有属性通过angular.equals比较都相等
- o1,o2都是NAN
- 两个同样的正则(/abc/=/abc/) 在JavaScript中返回false,在angular中返回true
addClass()
after()
append()
attr()
- Does not support functions as parametersbind()
- Does not support namespaces, selectors or eventDatachildren()
- Does not support selectorsclone()
contents()
css()
- Only retrieves inline-styles, does not callgetComputedStyle()
data()
detach()
empty()
eq()
find()
- Limited to lookups by tag namehasClass()
html()
next()
- Does not support selectorson()
- Does not support namespaces, selectors or eventDataoff()
- Does not support namespaces or selectorsone()
- Does not support namespaces or selectorsparent()
- Does not support selectorsprepend()
prop()
ready()
remove()
removeAttr()
removeClass()
removeData()
replaceWith()
text()
toggleClass()
triggerHandler()
- Passes a dummy event object to handlers.unbind()
- Does not support namespacesval()
wrap()
提交表单:
<input ng-model="data.username" /> <input ng-model="data.age" /> <button ng-click="add()">添加</button>
<script> angular.module('app', []) .controller('ctrl', function ($scope, $http) { $scope.add = function () { $http.post("/home/data", angular.toJson($scope.data)).then(function (res) { alert(res.data); }); } }); </script>
.net 接受前台请求:
public ActionResult data(string username,string age) { return Content(username + ":" + age); }
使用angular.toJson把对象转成Json字符串后向后台提交,如果表单内容很多,可以像上面使用data对象使代码量减少很多,如果添加更多属性,可以使用angular.extend:
$scope.add = function () { angular.extend($scope.data, { id: 22 }); alert($scope.data) var obj = angular.toJson($scope.data); $http.post("/home/data", obj).then(function (res) { alert(res.data); }); }
样式:
<li ng-repeat="(k,v) in list" style="{{$even?'color:red':''}}"> {{k.name}} </li>
<table> <tr ng-repeat="v in list"> <td ng-class="{red:v.age>20}">{{v.name}}</td> <td>{{v.age}}</td> <td></td> </tr> </table>
如果angularjs数组有重复项,则显示数组时不显示,可以使用track by $index:
$scope.arr = ['a', 'b', 'c', 'a']; <li ng-repeat="v in arr track by $index"> {{v}} </li>
全选和反选:
<ul> <li><input type="checkbox" ng-model="all" /></li> <li ng-repeat="v in [1,2]"> <input type="checkbox" ng-checked="all" /> </li> </ul>
过滤器:
<span>{{"abcdefg"|uppercase}}</span> <div>{{4324.2432|number:2}}</div> <div>{{"abcdefg"|limitTo:3:1}}</div> <div>{{d|date:'yyyy-MM-dd HH:dd:ss'}}</div> <div>{{arr|orderBy:false}}</div> <div>{{list|orderBy:'name':false}}</div> <div>{{list|filter:'3'}}</div>
angular.module('app', []) .controller('ctrl', function ($scope, $http) { $scope.arr = [4, 5, 6, 2, 3, 1]; $scope.list=[{name:"张三",age:11},{name:"张3三",age:21},{name:"张2三",age:31},{name:"张1三",age:12}] $scope.d = new Date().getTime(); });
排序:
<div> <div>{{list}}</div> <button ng-click=orderby()">按年龄排序</button> </div> <script> angular.module('app', []) .controller('ctrl', ['$scope', '$http', '$filter', function ($scope, $http, $filter) { $scope.list=[{name:"张三",age:11},{name:"李四",age:21},{name:"王五",age:31},{name:"赵六",age:12}] $scope.orderby = function () { if (arguments.callee["age"] == undefined) { arguments.callee["age"] = false; } arguments.callee["age"] = !arguments.callee["age"]; $scope.list = $filter('orderBy')($scope.list, 'age', arguments.callee["age"]); } }]); </script>
arguments.callee是保存点击状态的,有点像静态变量,每次点击其保存的变化值 ,点击改变排序,显示将会从小到大或从大到小来回切换排序,此方法可以应用到表格显示数据中,如下:
<table> <tr> <th ng-click="orderby('name')">姓名</th> <th ng-click="orderby('age')">年龄</th> </tr> <tr ng-repeat="item in list"> <td>{{item.name}}</td> <td>{{item.age}}</td> </tr> </table> <script src="~/Scripts/angular.min.js"></script> <script src="~/Scripts/underscore.js"></script> <script> angular.module('app', []) .controller('ctrl', ['$scope', '$http', '$filter', function ($scope, $http, $filter) { $scope.list = [{ name: "张三", age: 11 }, { name: "李四", age: 21 }, { name: "王五", age: 31 }, { name: "赵六", age: 12 }] $scope.orderby = function (field) { if (arguments.callee[field] == undefined) { arguments.callee[field] = false; } arguments.callee[field] = !arguments.callee[field]; $scope.list = $filter('orderBy')($scope.list, field, arguments.callee[field]); } }]); </script>
还可以如下方式:
angular.module('app', []) .controller('ctrl', ['$scope', '$http', '$filter', function ($scope, $http, $filter) { $scope.list = [{ name: "张三", age: 11 }, { name: "李四", age: 21 }, { name: "王五", age: 31 }, { name: "赵六", age: 12 }] $scope.status = { name: false, age: false }; $scope.orderby = function (field) { $scope.status[field] = !$scope.status[field]; $scope.list = $filter('orderBy')($scope.list, field, $scope.status[field]); } }]);
搜索:
html:
<div> <input ng-model="key" /> <table> <tr ng-repeat="item in list|filter:key"> <td>{{item.name}}</td> <td>{{item.age}}</td> <td></td> </tr> </table> </div>
js: angular.module("app", []).controller("ctrl", function ($scope) { $scope.age = 12; $scope.name = "wzh"; $scope.list = [ {name:"wzh",age:12}, {name:"zh",age:11}, {name:"wz",age:15}, {name:"qq",age:18}, {name:"zza",age:22} ] })
$watch:监听变量变化
<input ng-model="title" />{{error}} $scope.$watch("title", function (n, o) { $scope.error = n.length > 3 ? "不能超过3" : ""; });
监听对象
<input ng-model="data.title" />{{error}} $scope.$watch("data", function (n, o) { $scope.error = n.title.length > 3 ? "不能超过3" : ""; },true);
自定义过滤器:把手机号码后几位用*代替
<div>{{“13920353609”|truncate:5}}</div> app.filter("truncate", function () { return function (v, len) { len=len?len:3; return v.substr(0,11-len) + new String("*").repeat(len); } })
指令,
app.directive("hello", function () { return { template: "<div>{{name}}<input ng-model=name>", scope: {} } })
指令中的scope很重要,
scope参数是可选的,默认值为false,可选true、对象{};
-
false:共享父域
-
true:继承父域,且新建独立作用域
-
对象{}:不继承父域,且新建独立作用域
app.directive("test",function(){
return {
restrict : "E",
template : '<div name="{{name}}"></div>',
replace : true,
scope : {
name : "@"
}
}
<div ng-controller="mytest"> 父:<input type="text" ng-model="data.name" /> <test></test> </div>
app.directive("test",function(){ return { restrict : "E", template : '<div data="data">子指令:<input ng-model="data.name" /></div>', replace : true, scope : { data : "=" } }
“=”有双重绑定的功能,比如mytest控制器与test子指令进行双重绑定
<div ng-controller="mytest"> <test></test> </div> app.controller("mytest", function ($scope) { $scope.getName = function(){ console.log("jack"); } }); app.directive("test",function(){ return { restrict : "E", template : '<div get-name="getName()">子指令:<a href="javascript:void(0)" ng-click="getName()">点击调用父方法</a></div>', replace : true, scope : { getName : "&" }, controller : function($scope){ $scope.getName(); //"jack" }, link : function ($scope) { $scope.getName(); //"jack" } } });
“&”的意思是子指令能调用父控制器的方法,这里的指令template元素点击调用控制器的getName方法
指令中的控制器
var app = angular.module("app", []); app.directive("rere", [function () { return { retrict:"AE", templateUrl: '../html/1.html', controller: function ($scope) { $scope.list = [{ name: "张三", id: 1 }, { name: "张三", id: 2} ] } } }]);
1.html文件中:
<table> <tr ng-repeat="item in list"> <td>{{item.id}}</td> <td>{{item.name}}</td> </tr> </table>
ng-transclude
html: <div><h1 test age="1">我是原来内容</h1></div> js: app.directive("test", function () { return { template: "<div ><span ng-transclude ></span> {{age}} </div>", transclude:true, scope:{age:"="} } });
指令中Link使用:
<div> <hello smallstr="wzh" bgcolor="green" fontcolor="#fff">今天我最大</hello> <hello smallstr="zl" bgcolor="blue" fontcolor="#aaa">最好是今天</hello> <hello smallstr="qing" bgcolor="red" fontcolor="#fff">星期一</hello> <hello smallstr="xingni" bgcolor="yellow" fontcolor="#000">大家都回家</hello> </div>
app.directive("hello", function () { return { link:function(scope,elem,attr){ elem.css({ color: attr['fontcolor'] ,background:attr['bgcolor']}).html(elem.text()+"<small>"+attr["smallstr"]+"</small>"); } } })
可以简写成:
app.directive("hello", function () { return function (scope, elem, attr) { elem.css({ color: attr['fontcolor'], background: attr['bgcolor'] }).html(elem.text() + "<small>" + attr["smallstr"] + "</small>"); } });
做一个大一点的练习---tab标签,整个TAB标签就是用指令写成。
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> <script src="~/Scripts/angular.min.js"></script> <script src="~/Scripts/jquery-1.8.2.min.js"></script> <style> body { } </style> </head> <body ng-app="app" ng-controller="ctrl"> <wzhtab></wzhtab> <script> var app = angular.module("app", []); app.controller("ctrl", function ($scope) { }); app.directive("wzhtab", function () { return { templateUrl: "http/wzhtab.html", link: function (scope, elem, attr) { $(elem).on("click", "a", function () { $("a").removeClass("active"); $(this).addClass("active"); var index = $(this).index(); $(elem).find(".lists").hide().eq(index).show(); }); }, controller: function ($scope) { $scope.list = [ { title: "培训", data: [ { title: "asp.net", id: 1 }, { title: "PHP", id: 2 } ] }, { title: "学习", data: [ { title: "asp.net", id: 3 }, { title: "PHP", id: 4 } ] }, ] } } }); </script> </body> </html>
wzhtab.html
<style> a { border: 1px solid #000; padding: 5px 10px; margin: 0; } a.active { background: #888; color: #fff; } .lists { border: 1px solid #000; width: 300px; height: 100px; padding: 20px; margin-top: 5px; } </style> <div> <a ng-repeat="item in list" href="#" ng-class="{active:$first}">{{item.title}}</a> <div class="lists" ng-repeat="item in list" ng-style="{display:$first?'block':'none'}"> <ul> <li ng-repeat="v in item.data">{{v.id}}.{{v.title}}</li> </ul> </div> </div>
在指令link中使用jquery ,可以$(elem),由于模板中元素是后添加,在指令 link操作dom事件时,使用了on绑定函数
问题:能不能使用普通jquery改变angularjs中的变量,并且显示数据出自动发生改变呢?
比如如下:用 angularjs事件方法,可以在button上添加ng-click="change()" ,可以改变,如果不用这种方法,使用jquery方法,这时name属性值已经发生了变化,但不会更新到界面上。
<div> {{name}} <button id="btn">改变</button> </div> var app = angular.module("app", []); app.controller("ctrl", function ($scope) { $scope.name = "aaa"; //$scope.change = function () { // $scope.name = "bbb"; //} $("#btn").click(function () { $scope.name = "bbb"; }); });
如果想更新到界面上,可以使用$apply()
$("#btn").click(function () { $scope.name = "bbb"; $scope.$apply(); });