收藏比较典型的代码结构,供自我学习

1
2
3
4
5
6
7
8
9
10
11
12
13
//ng-controller指令来创建一个简单的控制器定义:
<div ng-app="" ng-controller="MyController">
请输入一个名字:<input type="text" ng-model="person.name"> //初始会显示world
Hello <span ng-bind="person.name"></span>
</div>
<script>
//使用$scope
function MyController($scope) {
$scope.person = {
name: "world"
};
}
</script>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//ng-controller指令定义方法使用
<div ng-app="" ng-controller="MyController">
Your name:
<input type="text" ng-model="username">
<button ng-click="sayHello()">打招呼</button>
<hr />
{{greeting}}
</div>

<script>
function MyController($scope) {
$scope.username = 'World';
$scope.sayHello = function() {
$scope.greeting= 'Hello ' + $scope.username + '!';
};
}
</script>

//类比逻辑
<select onchange="hiveTypeCheck(this)"></select>
1
2
3
4
5
6
7
8
//原始事件方法处理
<button onclick='myCtr()'>第一个按钮</button> <br><br>
<button onclick='this.innerText="点击了第二个按钮";document.body.style.cssText="background-color:red";'>第二个按钮</button>
<script>
function myCtr(){
alert('点击了第一个按钮');
}
</script>

1
2
//表达式连接字符串
<td> {{ 'Name:'+ x.name +' ,Age:'+ x.age}} </td>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
//过滤器uppercase、lowercase对字符串转换大、小写
<div ng-app="">
请输入: <input type="text" ng-model="name">
结果为: {{ name | uppercase}} //过滤器位置
</div>
//filter过滤器可以过滤数组并从中选择出一个子集出来,用法是“filter:模型名称”
<div ng-app="" ng-init="friends = [
{name:'tom', age:16},
{name:'jerry', age:20},
{name:'garfield', age:22}]">


输入过滤:<input type="text" ng-model="name" >
<ul style="list-style-type:none">
<li> 姓名,年龄</li>
<li ng-repeat="x in friends | filter:name"> //过滤器位置
{{ x.name + ' , ' + x.age }}
</li>
</ul>
</div>
//编译后的代码 多了class东东
<ul style="list-style-type:none">
<li> 姓名,年龄</li>
<!-- ngRepeat: x in friends | filter:name -->
<li ng-repeat="x in friends | filter:name" class="ng-scope ng-binding">
tom , 16
</li>
<li ng-repeat="x in friends | filter:name" class="ng-scope ng-binding">
jerry , 20
</li>
<li ng-repeat="x in friends | filter:name" class="ng-scope ng-binding">
garfield , 22
</li>
</ul>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//模板、指令和视图
<!-- 模板文件 -->
<html>
<head>
<script src="js/angular.min.js"></script>
<script>
angular.module("ezstuff",[])//创建模块ezstuff
.directive("ezClock",function(){//在模块上注册指令ezClock的类工厂 封装格式 ezClock驼峰标识 link的参数
return {
restrict : "E",
replace : true,
template : "<div class='clock'></div>",
link : function(scope,element,attrs){
setInterval(function(){
//获取当前时间
var d = new Date();
//element对应引用该指令的DOM对象的jqLite封装
element.text(d.toString());
},1000);
}
}
})
</script>

</head>
<!-- 内置的ng-app指令通知编译器启动AngularJS框架-->
<body ng-app="ezstuff">
<!-- 我们自己定义的ez-clock指令通知编译器生成时钟widget-->
<ez-clock></ez-clock>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    //将数据传递给指令
<script>
//sb变量建立在window对象上
var sb = {
name: "somebody",
gender: "male",
age: 28
};
angular.module("ezstuff", [])
.directive("ezNamecard", function () {
return {
restrict: "E",
template: "<div class='namecard'>",
replace: true,
link: function (scope, element, attrs) {
//读取data属性值,获得变量名,通过eval得到其值
var sb = eval(attrs.data);
//填充DOM元素内容
element.append("<div>name : " + sb.name + "</div>")
.append("<div>gender : " + sb.gender + "</div>")
.append("<div>age : " + sb.age + "</div>")
}
};
});
</script>

<body ng-app="ezstuff" class="ng-scope">
<!--使用data属性向指令实现代码传递变量名-->
<ez-namecard data="window.sb"></ez-namecard>
</body>
-------------------------------编译后的html代码如下-----------------------------
<body ng-app="ezstuff" class="ng-scope"> //根节点多了class、data属性在新生成标签里出现
<!--使用data属性向指令实现代码传递变量名-->
<div class="namecard" data="window.sb">
<div>name : somebody</div>
<div>gender : male</div>
<div>age : 28</div>
</div>
</body>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//启动编译时会执行一次$watch里的回调方法
angular.module("ezstuff", [])
.directive("ezNamecard", function () {
return {
restrict: "E",
template: "<div class='namecard'></div>",
replace: true,
link: function (scope, element, attrs) {
element.append("<div>name : <span></span></div>")
.append("<div>gender :<span></span></div>")
.append("<div>age : <span></span></div>");
scope.$watch('sb',function (nv,ov) {
var spans = element.find('span');
spans[0].innerText = nv.name; //取出的是dom对象
spans[1].innerText = nv.gender;
spans[2].innerText = nv.age;
},true);
setInterval(function(){
scope.$apply("sb.age=sb.age+1;") //好像必须这样才生效?
},1000);
}
};
});
1
2
3
4
5
//获得注入器 再得到功能组件
var injector = angular.injector(['ng']);
injector.invoke(function($http){
//do sth with $http
});
1
2
3
4
5
6
7
8
//ready事件  注入器的参数
angular.element(document).ready(function(){
angular.injector(["ng"]).invoke(function($http){
//将$http对象转成字符串显示出来
var e = document.querySelector("#logger");
angular.element(e).text($http.toString());
});
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
//我们定义了一个简单的服务类,这个服务类的实例就是一个字符串:“hello,world!”。
//我们使用"ezHello"作为其服务名在注入器里注册,并通过注入器将这个实例显示出来。
//在ezstuff模块上登记一个服务ezHello
angular.module("ezstuff",[])
.provider("ezHello",function(){
//$get方法是一个类工厂,返回服务的实例
this.$get = function(){
return "hello,world!";
};
});

angular.element(document).ready(function(){
//注入器里含有ezstuff模块名
//使用创建新的注入器方式 原因html中没有ng-app指令
angular.injector(["ng","ezstuff"]).invoke(function(ezHello){
//将ezHello实例对象转成字符串显示出来
var e = document.querySelector("#logger");
angular.element(e).text(ezHello);
});
});
//注html中并没有ng-app指令
<html>
<head>
<script src="js/angular.min.js"></script>
</head>
<body>
<!--在这里显示ezHello实例的内容-->
<div id="logger"></div>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
//模拟引导启动过程
angular.element(document).ready(function(){
//第一步:创建注入器并保存到根对象的data中
var injector = angular.injector(["ng","ezstuff"]);
angular.element(document).data("$injector",injector);
//第二步:创建根作用域并保存到根对象的data中
var rootScope = injector.get("$rootScope"); //$rootScope是一个服务啊
angular.element(document).data("$rootScope",rootScope);
//第三步:编译DOM树
var compile = injector.get("$compile"); //$compile也是个服务啊
compile(document)(rootScope);
})
1
2
3
4
5
6
7
8
9
10
11
//控制器实际上就是一个JavaScript的类/构造函数
//控制器类定义
var myControllerClass = function($scope){
//模型属性定义
$scope.text = "...";
//模型方法定义
$scope.do = function(){...};
};
//在模块中注册控制器
angular.module('someModule',[])
.controller("myController",myControllerClass);
1
2
//ng-src指令
<div><img ng-src="{{vm.sb.photo}}"></div>
1
2
3
4
5
6
//参数的形式
directive指令的参数$scope,link参数scope,element,attrs;
controller控制器的参数$scope。
//数据绑定
directive指令需要$apply调用
controller控制器不需要$apply调用?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//控制器的定义  数据绑定没有$apply
var ezControllerClass = function($scope){
//view model
$scope.vm = {
sb : {
name : "Jason Stantham",
gender : "male"
},
shuffle : function(){
var repo = [
{name:"Jason Stantham",gender:"male"},
{name:"Jessica Alba",gender:"female"},
{name:"Nicolas Cage",gender:"male"},
{name:"崔永元",gender:"male"},
{name:"Sheetal Sheth",gender:"female"},
{name:"Barack Obama",gender:"male"}
];
var idx = Math.floor(Math.random()*repo.length);
$scope.vm.sb = repo[idx];
}
};
};
angular.module("ezstuff",[]).controller("ezController",ezControllerClass);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//可配置的服务
function doCalc(){
var injector = angular.injector(["ezstuff"]),
mycalculator = injector.get("ezCalculator"),
ret = mycalculator.add(3,4);
document.querySelector("#result").textContent = ret;
}
//区分服务名称与注册服务名称
angular.module("ezstuff",[])
.provider("ezCalculator",function(){
var currency = "$";
this.setLocal = function(l){
var repo = {
"CN":"¥",
"US":"$",
"JP":"¥",
"EN":"€"
};
if(repo[l]) currency = repo[l];
};
this.$get = function(){
return {
add : function(a,b){return currency + (a+b);},
subtract : function(a,b){return currency + (a-b);},
multiply : function(a,b){return currency + (a*b);},
divide: function(a,b){return currency + (a/b);}
}
};
})
.config(function(ezCalculatorProvider){ //注入的名称
ezCalculatorProvider.setLocal("CN");
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
//factory方法要求提供一个对象工厂,调用该类工厂将返回服务实例
var myServiceFactory = function(){
return ...
};
angular.module("myModule",[])
.factory("myService",myServiceFactory);
//INSIDE:AngularJS会将factory方法封装为provider,上面的示例等同于:
var myServiceFactory = function(){
return ...
};
angular.module("myModule",[])
.provider("myService",function(){
this.$get = myServiceFactory;
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//service方法要求提供一个构造函数,AngularJS使用这个构造函数创建服务实例:
var myServiceClass = function(){
this.method1 = function(){...}
};
angular.module("myModule",[])
.service("myService",myServiceClass);
//INSIDE:AngularJS会将service方法封装为provider,上面的示例等同于:
var myServiceClass = function(){
//class definition.
};
angular.module("myModule",[])
.provider("myService",function(){
this.$get = function(){
return new myServiceClass();
};
});
1
2
3
4
5
6
7
8
9
10
11
//有时我们需要在不同的组件之间共享一个变量,可以将这种情况视为一种服务:provider返回的总是变量的值。
//value方法提供了对这种情况的简化封装:
angular.module("myModule",[])
.value("myValueService","cx129800123");
//INSIDE:AngularJS会将value方法封装为provider,上面的示例等同于:
angular.module("myModule",[])
.provider("myService",function(){
this.$get = function(){
return "cx129800123";
};
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//constant方法
function doCalc(){
var injector = angular.injector(["ezstuff"]),
mycalculator = injector.get("ezCalculator"),
ret = mycalculator.add(3,4);
document.querySelector("#result").textContent = ret;
}
angular.module("ezstuff",[])
.constant("ezCurrency","CN") //constant方法
.provider("ezCalculator",function(){
var currency = "$";
this.setLocal = function(l){
var repo = {
"CN":"¥",
"US":"$",
"JP":"¥",
"EN":"€"
};
if(repo[l]) currency = repo[l];
};
this.$get = function(){
return {
add : function(a,b){return currency + (a+b);},
subtract : function(a,b){return currency + (a-b);},
multiply : function(a,b){return currency + (a*b);},
divide: function(a,b){return currency + (a/b);}
}
};
})
.config(function(ezCurrency,ezCalculatorProvider){ //constant方法的注入名称
ezCalculatorProvider.setLocal(ezCurrency);
});
1
2
3
4
5
6
7
8
9
10
11
//定义指令的类工厂
var directiveFactory = function(injectables){
//指令定义对象
var directiveDefinationObject = {
...
};
return directiveDefinationObject;
};
//在模块上注册指令
angular.module("someModule",[])
.directive("directiveName",directiveFactory);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//你可能注意到模板的内容稍微修改了一下,这是因为replace为true时,要求模板有一个根节点。否报错Error: [$compile:tplrt]。
angular.module("ezstuff",[])
.controller("ezCtrl", ["$scope", function($scope) { // 控制器获取依赖---数组形式
$scope.customer = {
name: "Naomi",
address: "1600 Amphitheatre"
};
}])
.directive("ezCustomer", function() {
return {
restrict:"E",
replace:true,
template: "<div>Name: {{customer.name}} Address: {{customer.address}}</div>"
};
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//指令的scope---使用隔离的作用域
//通过设置scope属性,指令的每个实例都将获得一个隔离的本地作用域
<!--dom-->
<body>
<div ng-controller="ezCtrl">
<ez-customer sb="Emmy"></ez-customer>
<ez-customer sb="Edison"></ez-customer>
</div>
</body>
<!--js-->
angular.module("ezstuff",[])
.controller("ezCtrl", ["$scope", function($scope) {
$scope.Emmy = {
name: "Emmy",
address: "1600 Amphitheatre"
};
$scope.Edison = {
name: "Edison",
address: "2500 Amphitheatre"
};
}])
.directive("ezCustomer", function() {
return {
restrict:"E",
replace:true,
scope:{
customer:"=sb", //=绑定外部scope
},
template: "<div>Name: {{customer.name}} Address: {{customer.address}}</div>"
};
});
<!--结果-->
Name: Emmy Address: 1600 Amphitheatre
Name: Edison Address: 2500 Amphitheatre
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//link函数中启动定时器,并在定时器中更新DOM---指定显示格式的小时钟指令
<!--Dom-->
<div ng-controller="ezCtrl">
Date format: <input ng-model="format"> <hr/>
Current time is: <span ez-current-time="format"></span>
</div>
<!--js-->
angular.module("ezstuff", [])
.controller("ezCtrl", ["$scope", function($scope) {
$scope.format = "M/d/yy h:mm:ss a";
}])
.directive("ezCurrentTime", ["$interval", "dateFilter", function($interval, dateFilter) { //
//定义link函数
function link(scope, element, attrs) {
var format,timeoutId;
//更新DOM内容
function updateTime() {
element.text(dateFilter(new Date(), format));
}
//监听时钟格式
scope.$watch(attrs.ezCurrentTime, function(value) {
format = value;
updateTime();
});
//在DOM对象销毁时注销定时器
element.on("$destroy", function() {
$interval.cancel(timeoutId);
});
//启动定时器
timeoutId = $interval(function() {
updateTime(); //update DOM
}, 1000);
};
//返回指令定义对象
return {
link: link
};
}]);
//有几点解释下:
//*我们在scope上使用$watch()方法对format的值进行监听,并使用这个值调整显示格式。
//*我们监听element的$destroy事件,这个事件是在DOM对象销毁时触发。我们在这个事件触发时销毁定时器以释放资源。
//*我们使用了AngularJS内置的$interval服务,而不是setInterval()函数创建定时器。其cancel方法。
//*我们使用了AngularJS内置的dateFilter过滤器服务,对时间的显示进行格式化。和$interval一样,dateFilter服务也是通过注入器注入的。
1
2
3
4
5
//在代码中使用过滤器
angular.module("ezstuff",[])
.controller("ezCtrl",function($scope,numberFilter,currencyFilter){
$scope.total = currencyFilter(numberFilter(123,2));
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//过滤器对象工厂定义
var ezUCFilterFactory = function(){
//过滤器对象返回的是一个过滤函数
return function(input,cap){
if(!cap) return input.toUpperCase();
var output = input.replace(/\b\w+\b/g, function(word) {
return word.substring(0,1).toUpperCase()+word.substring(1); //首字母大写
});
return output;
}
};
angular.module("ezstuff",[])
//使用模块的filter()接口注册过滤器
.filter("ezUC",ezUCFilterFactory);
<!--DOM-->
<body ng-init="text='just a demo!'">
<p>{{text|ezUC:true}}</p>
</body>
1
2
3
4
5
6
//当前作用域与根作用域 同时注入
angular.module("myApp",[])
.controller("ctrl01",function($scope,$rootScope){
$scope.uname="xiaogao";
$rootScope.uname="laogao";
});
1
2
//内置过滤器
<h1>{{birthday | date:'yyyy年MM月dd日' }}</h1>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
//指令中监听数据的变化、数据变化的传播
<!--DOM-->
<body ng-app="ezstuff" ng-init="sb = {name:'somebody',gender:'male',age:28}">
<!-- 下面两个指令都绑定到变量sb上-->
<ez-namecard-editor data="sb"></ez-namecard-editor>
<div ez-logger data="sb"></div>
</body>
<!--js-->
angular.module("ezstuff", [])
.directive("ezNamecardEditor", function () {
return {
restrict: "E",
template: "<ul class='nceditor'></ul>",
replace: true,
link: function (scope, element, attrs) {
//获得变量名称
var model = attrs.data;
//展开HTML模板,使用field属性标记对应字段
element.append("<li>name : <input type='text' field='name'></li>")
.append("<li>gender : <input type='text' field='gender'></li>")
.append("<li>age : <input type='text' field='age'></li>");

//监听DOM事件,变化时修改变量值
element.find("input").on("keyup", function (ev) {
var field = ev.target.getAttribute("field");
scope[model][field] = ev.target.value;
//将对scope的修改进行传播
scope.$apply("");
});
}
};
})
.directive("ezLogger", function () {
return {
restrict: "A",
link: function (scope, element, attrs) {
var model = attrs.data; //获得变量名称
scope.$watch(model, function (nv) {
var cnt = JSON.stringify(nv, null, " "); //stringify的用法
element.html("<pre>" + cnt + "</pre ");
}, true);
}
};
});

1
2
3
4
//1、即便不存在user对象或user.sb对象 也会在输入框输入值后自动创建 也就如果$scope里没user。
//2、当user为空对象{}或不存在时,输入框什么都没有 异常处理了
//3、双向数据绑定
<input type="text" ng-model="user.sb.name" />
1
2
3
4
//遍历性别对象  track by使用
<label ng-repeat="(key, val) in genders track by $index">
<input type="radio" name="gender" value="{{key}}" ng-checked="list.gender==key">{{val}}
</label>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//双重遍历  1、id、name的值形式  2、ng-checked的值为函数及参数 3、ng-click的参数$event
<div data-ng-repeat="category in tagcategories">
<div>{{ category.name }}</div>
<div data-ng-repeat="tag in category.tags">
<div>
<input type="checkbox" id={{tag.id}} name="{{tag.name}}" ng-checked="isSelected(tag.id)" ng-click="updateSelection($event,tag.id)"> {{ tag.name }}
</div>
</div>
<hr>
</div>
//$event.target、checkbox.checked、$scope.selected.splice、$scope.selectedTags.splice
$scope.selected = [];
$scope.selectedTags = [];
var updateSelected = function(action,id,name){
if(action == 'add' && $scope.selected.indexOf(id) == -1){
$scope.selected.push(id);
$scope.selectedTags.push(name);
}
if(action == 'remove' && $scope.selected.indexOf(id)!=-1){
var idx = $scope.selected.indexOf(id);
$scope.selected.splice(idx,1);
$scope.selectedTags.splice(idx,1);
}
}

$scope.updateSelection = function($event, id){
var checkbox = $event.target;
var action = (checkbox.checked?'add':'remove');
updateSelected(action,id,checkbox.name);
}

$scope.isSelected = function(id){
return $scope.selected.indexOf(id)>=0;
}
1
2
3
4
5
6
7
8
9
10
11
// 提示:模块除了可以加载其他依赖模块,亦可以创建配置、控制器、服务、指令、测试之类的。
// 本实例为模块加载其他依赖模块,并创建一个控制器
var app = angular.module('NameApp', ['ngAnimate']);
app.controller("SecondCtrl", function($scope){
$scope.names = [
{name: 'a乔乐', age:'25'},
{name: 'b周迅', age:'40'},
{name: 'c魏瑞', age:'25'},
{name: 'd展昭', age:'98'}
];
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//ngAnimate模块里的animate-repeat class类  后面动画样式
.animate-repeat {
line-height:40px;
list-style:none;
box-sizing:border-box;
}

.animate-repeat.ng-move,.animate-repeat.ng-enter,.animate-repeat.ng-leave {
-webkit-transition:all linear 0.5s;
transition:all linear 0.5s;
}

.animate-repeat.ng-leave.ng-leave-active,.animate-repeat.ng-move,.animate-repeat.ng-enter {
opacity:0;
max-height:0;
}

.animate-repeat.ng-leave,.animate-repeat.ng-move.ng-move-active,.animate-repeat.ng-enter.ng-enter-active {
opacity:1;
max-height:40px;
}
1
2
// $parent.$index与$index
<span class="nested-index ng-binding" ng-bind="$parent.$index + '-' + $index">0-0</span>
1
2
3
4
5
6
7
8
9
10
/*
* return a copy of an object with only non-object keys
* we need this to avoid circular references
*/
function simpleKeys (original) {
return Object.keys(original).reduce(function (obj, key) {
obj[key] = typeof original[key] === 'object' ? '{ ... }' : original[key];
return obj;
}, {});
}
1
2
```
```html
1
2
```
```html
1
2
```
```html

Comments

去留言
2016-06-15

⬆︎TOP