说明:《angularjs权威教程》出版较早,于2014年出版,主要介绍angualrjs1的内容
优化启发:(1)尽可能的精简控制器,在控制器中进行DOM操作或者数据数据操作是不好的实践
《第2章》控制器:
由于JavaScript自身的特点,以及它在传递值和引用时的不同处理方式,通常认为,在视图中通过对象的属性而非对象本身来进行引用绑定,是Angular中的最佳实践。
如果把这个最佳实践应用到上面时钟的例子中,需要把视图中的代码改写成下面这样:
<!doctype html>
<htmlng-app>
<head>
<script src="https://ajax.googleapis.com/ajax/ libs/angularjs/1.2.13/angular.js"></script>
</head>
<body>
<div ng-controller="MyController">
<h1>Hello {{ clock.now }}!</h1>
</div>
<script type="text/javascript" src="js/app.js"></script>
</body>
</html>
在这个例子中,相比每秒钟都更新$scope.clock
,更新clock.now
的值会是更好的选择。有了这个优化后,我们将对反映数据变化的逻辑进行如下修改:
// 在app.js中
angular.module('myApp', [])
.controller('MyController', function($scope, $timeout) {
$scope.clock = {};
var updateClock = function() {
$scope.clock.now = new Date();
$timeout(function() {
updateClock();
}, 1000);
};
updateClock();
});
将所有绑定都通过这样的形式放在视图中是个非常好的主意。
《第3章》模块(module)
module的优点:
- 保持全局命名空间的清洁;
- 编写测试代码更容易,并能保持其清洁,以便更容易找到互相隔离的功能;
- 易于在不同应用间复用代码;
- 使应用能够以任意顺序加载代码的各个部分。
$scope
对象在AngularJS中充当数据模型,但与传统的数据模型不一样,$scope
并不负责处理和操作数据,它只是视图和HTML之间的桥梁,它是视图和控制器之间的胶水。
$scope
的所有属性,都可以自动被视图访问到.
作用域有以下的基本功能:
- 提供观察者以监视数据模型的变化;
- 可以将数据模型的变化通知给整个应用,甚至是系统外的组件;
- 可以进行嵌套,隔离业务功能和数据;
- 给表达式提供运算时所需的执行环境。
设计良好的应用会将复杂的逻辑放到指令和服务中。通过使用指令和服务,我们可以将控制器重构成一个轻量且更易维护的形式:
简洁的控制器:
angular.module('myApp', [])
.controller('MyController', function($scope,UserSrv) {
// 内容可以被指令控制
$scope.onLogin = function(user) {
UserSrv.runLogin(user);
};
});
《第6章》表达式
angularjs会在运行$digest循环的过程中自动解析表达式
通过$parse这个内部服务来进行表达式的运算,这个服务能访问当时的作用域
也可手动解析表达式
angular.module("myApp", [])
.controller('MyController', function($scope,$parse) {
$scope.$watch('expr', function(newVal, oldVal, scope) {
if (newVal !== oldVal) {
// 用该表达式设置parseFun
var parseFun = $parse('expr');
// 获取经过解析后表达式的值
$scope.parsedValue = parseFun(scope);
}
});
});
插值字符串$interpolate
《第7章》过滤器
使用方法:(1){{name | uppercase}}
(2) 注入$filter $scope.name = $filter('lowercase')('Ari')
内置过滤器: currency data(date:'hh:mm:ss') filter json limitTo lowercase number orderBy
自定义过滤器
angulae.module('myApp.filters',[])
.filter('capitalize', function(){
return function(input){.....}
})
表单验证: novalidate:取消默认验证行为
require ng-minlength ng-maxlength ng-pattern="[a-zA-Z]"
表单各项包括属性:$pristine $dirty $invalid $valid 对应样式 ng-prinstuib ng-dirty ng-invalid ng-valid
使用$parsers 和 $formatters
-
当用户同控制器进行交互,并且
ngModelController
中的$setViewValue()
方法被调用时,$parsers
数组中的函数会以流水线的形式被逐个调用。第一个$parse
被调用后,执行结果会传递给第二个$parse
,以此类推。这些函数可以对输入值进行转换,或者通过
$setValidity()
函数设置表单的合法性。使用
$parsers
数组是实现自定义验证的途径之一。例如,假设我们想要确保输入值在某两个数值之间,可以在$parsers
数组中入栈一个新的函数,这个函数会在验证链中被调用。每个
$parser
返回的值都会被传入下一个$parser
中。当不希望数据模型发生更新时返回undefined
。angular.module('myApp') .directive('oneToTen', function() { return { require: '?ngModel', link: function(scope, ele, attrs, ngModel) { if (!ngModel) return; ngModel.$parsers.unshift( function(viewValue) { var i = parseInt(viewValue); if (i >= 0 && i < 10) { ngModel.$setValidity('oneToTen', true); return viewValue; } else { ngModel.$setValidity('oneToTen', false); return undefined; } }); } }; });
-
$formatters
当绑定的
ngModel
值发生了变化,并经过$parsers
数组中解析器的处理后,这个值会被传递给$formatters
流水线。同$parsers
数组可以修改表单的合法性状态类似,$formatters
中的函数也可以修改并格式化这些值。比起单纯的验证目的,这些函数更常用来处理视图中的可视变化。例如,假设我们要对某个值进行格式化。通过
$formatters
数组可以在这个值上执行过滤器:angular.module('myApp') .directive('oneToTen', function() { return { require: '?ngModel', link: function(scope, ele, attrs, ngModel) { if (!ngModel) return; ngModel.$formatters.unshift(function(v) { return $filter('number')(v); }); } }; });