Table of Contents
1. application life-cycle
2. provider
- AngularJS的injector会使用recipes创建两类对象
- services: 接口由开发人员自己定义
- special purpose objects:包括directive, controller, filter和animation
- AngularJS的有五种recipes定义如何创建对象:
- Value
- Factory
- Service
- Provider
- Constant
注意不要把Provider和Factory混淆。
在Configuration阶段(即module.config函数中),可以引用constant和provider。
- Factory和Service最常用(optool scala使用factory来定义rest api)。
- factory可以传入函数或者javascript的primitives
- service只能之传入一个构造函数指针
- provider需要返回的对象有一个$get函数, Provider是底层实现,其他的都是syntactic sugar。
// value
myApp.value('clientId', 'a12345654321x');
// factory
myApp.factory('unicornLauncher', ["apiToken", function(apiToken) {
return new UnicornLauncher(apiToken);
}]);
// service
myApp.service('unicornLauncher', ["apiToken", UnicornLauncher]);
// provider
myApp.provider('unicornLauncher', function UnicornLauncherProvider() {
var useTinfoilShielding = false;
this.useTinfoilShielding = function(value) {
useTinfoilShielding = !!value;
};
this.$get = ["apiToken", function unicornLauncherFactory(apiToken) {
// let's assume that the UnicornLauncher constructor was also changed to
// accept and use the useTinfoilShielding argument
return new UnicornLauncher(apiToken, useTinfoilShielding);
}];
});
// constant
myApp.constant('planetName', 'Greasy Giant');
- All special purpose objects except for the Controller are defined via Factory recipes.
Features / Recipe type
|
Factory
|
Service
|
Value
|
Constant
|
Provider
|
can have dependencies
|
yes
|
yes
|
no
|
no
|
yes
|
uses type friendly injection
|
no
|
yes
|
yes*
|
yes*
|
no
|
object available in config phase
|
no
|
no
|
no
|
yes
|
yes**
|
can create functions
|
yes
|
yes
|
yes
|
yes
|
yes
|
can create primitives
|
yes
|
no
|
yes
|
yes
|
yes
|
* at the cost of eager initialization by using ``new`` operator directly
** the service object is not available during the config phase, but the provider instance is
3. Scope and Digest
- Scope object
- Scope.$watch: 变更注册。注册一个返回值的函数和一个回调函数,但值变化时,调用回调函数
- Scope.$digest: 变更通知。遍历$watch注册的函数,根据值的变化,调用相应的回调函数
- Scope.$apply: 用于外部库接入AngularJS。执行一个函数,该函数用来修改Scope,然后调用$digest触发变更通知
- Scope.$eval: 执行一个函数,并传递Scope作为其第一个参数
- Scope.$evalAsync:注册一个将来执行的函数,类似于Javascript里的setTimeout
- Scope.$applyAysnc: 延迟执行apply
3.1. scope分类
- angularJS里scope的继承,依赖javascript的prototype chain
- 这些东西会创建新的scope: ng-repeat, ng-include, ng-switch, ng-view, ng-controller, directive with
scope: true, directive withtransclude: true. - ng-repeat创建scope的方式比较特别,在child scope里增加一个会以repeat的变量名为名字的属性
- directive有三种:
- scope: false,直接使用现有的scope,需要小心
- scope: true,创建自己的scope,并有继承关系
- scope: {…},isolated scope 创建自己的scope,没有继承parent scope,但是又$parent属性。这种scope又有三种绑定方式
- one way: @ 需要传入字符串?或者{{var}}
- two way: = 传入父scope的属性
- bind to parent scope expressions: &
<my-directive interpolated="{{parentProp1}}" twowayBinding="parentProp2"> and scope: { interpolatedProp: '@interpolated', twowayBindingProp: '=twowayBinding' }
Assume the directive does this in its linking function:
scope.someIsolateProp = "I’m isolated"- directive的transclude: true会创建一个新的scope(如下),其中的$$nextSibling可以被ng-transclude使用
3.2. isolated scope中的 &
Developer Guide中的例子
script.js
angular.module('docsIsoFnBindExample', [])
.controller('Controller', ['$scope', '$timeout', function($scope, $timeout) {
$scope.name = 'Tobias';
$scope.message = '';
$scope.hideDialog = function (message) {
$scope.message = message;
$scope.dialogIsHidden = true;
$timeout(function () {
$scope.message = '';
$scope.dialogIsHidden = false;
}, 2000);
};
}])
.directive('myDialog', function() {
return {
restrict: 'E', // (1.1)
transclude: true,
scope: {
'close': '&onClose' // (1.2)
},
templateUrl: 'my-dialog-close.html'
};
});
index.html
{{message}}
<my-dialog ng-hide="dialogIsHidden" on-close="hideDialog(message)"> // (2)
Check out the contents, {{name}}!
</my-dialog>
my-dialog-close.html
<div class="alert">
<a href class="close" ng-click="close({message: 'closing for now'})">×</a> // (3)
<div ng-transclude></div>
</div>
解读如下:
- (1.1) (1.2) scope的close属性绑定到onClose element
- (2) 这里angluarJS会使用 $parse,解析出一个function,在调用该function时,需要传递context和locals对象。这个表达式中涉及identifier需要在context或locals对象中定义(以字段的形式)
- (3) 当click时,调用(2)中的function,context为父类的scope, locals为 {message: 'closing for now'}
- 可以看出(2)和(3)中的message需要匹配,否则无法传递参数

0 评论:
Post a Comment