Angular零星知识点(一)
逛知乎看到一个问题,看了之后自惭形秽,半年多,感觉一直是朦朦胧胧的,看来还是要巩固一下基础
一、factory、service以及provider
之前做ppt正好查了相关方面,可惜侧重点是factory,没仔细看三者区别
参考了三篇文章,有两篇介绍了services的几种类型,一篇前端乱炖,一篇CSDN,还有一篇重点是factory、service和provider的差异,开源上的。
之后又参考了两篇,发现之前认识有偏差
参考: 那伤不起的provider们啊;淺談Angular.js的Provider機制
总结一下:
factory、service等都是$provider服务所提供的方法,是将可共用代码包装注册到组件中,然后注入到需要用到的地方
$http就是Angular提供的provider
provider是所以功能的基底,factory、service等都是provider包装后的一种语法糖,通过$get方法将单例注入应用,config阶段可配置provider
factory能够返回任何数据类型,第二个参数就是$get对应的函数实现
service返回的是new出来的JS类的一个实例化对象,只实例化一次
value和constant,都是返回常量,value可修改,constant声明后不可修改,但constant可在config中注入
decorator可装饰除constant外的$provider,接收想要装饰的$provider的名字并且在回调函数中接收一个$delegate来代表实际上的$provider实例
$provider优点:
1. 为应用提供通用的服务,形式可以是常量或对象
2. 便于模块化
3. 便于单元测试
二、Angular中的数据绑定,dirty-checking,$diges
参考:关于 AngularJS 的数据绑定 ;理解$watch ,$apply 和 $digest --- 理解数据绑定过程
总结一下:
angular context 事件循环的执行环境
当绑定一个属性到页面上时,就会往$watch队列插入一条$watch,$watch用来监视model的变化【{{}};ng-model;ng-repeat也算一个】
当浏览器接收到可以被angular context处理的事件时,就会触发$digest循环,它会遍历$watch队列
这个循环叫做dirty-checking
- 我们按下按钮
- 浏览器接收到一个事件,进入
angular context
。$digest
循环开始执行,查询每个$watch
是否变化。- 由于监视
$scope.name
的$watch
报告了变化,它会强制再执行一次$digest
循环。- 新的
$digest
循环没有检测到变化。- 浏览器拿回控制权,更新与
$scope.name
新值相应部分的DOM。
当前循环完成后,会在执行一次循环确保model不再发生变化,最多循环10次,之后抛出异常,防止死循环
每一个进入angular context的事件都会触发$digest循环,每输入一个字母就会循环检查整个队列的$watch
而调用$apply就会进入angular context
$apply与$digest区别:
1) 最直接的差异是,
$apply
可以带参数,它可以接受一个函数,然后在应用数据之后,调用这个函数。所以,一般在集成非 Angular 框架(比如jQuery)的代码时,可以把代码写在这个里面调用。2) 当调用
$digest
的时候,只触发当前作用域和它的子作用域上的监控,但是当调用$apply
的时候,会触发作用域树上的所有监控。
需要$apply的场景:
典型的需要调用
$apply()
方法的场景是:1) 使用了 JavaScript 中的
setTimeout()
来更新一个scope model
2) 用指令设置一个
DOM
事件listener
并且在该listener
中修改了一些models
angular中$timeout会自动调用$apply
三、Angular1.2版本加入的controller as与$scope
参考: angular controller as syntax vs scope ;用$scope还是用controller as ;AngularJS: "Controller as" or "$scope"?
区别:
$scope:
angular.module("app",[]) .controller("demoController",["$scope",function($scope){ $scope.title = "world"; }]) <div ng-app="app" ng-controller="demoController"> hello : {{title}} ! </div>
controller as:
angular.module("app",[]) .controller("demoController",[function(){ this.title = "world"; }]) <div ng-app="app" ng-controller="demoController as demo"> hello : {{demo.title}} ! </div>
简单总结一下就是:
controller as不依赖于$scope,所谓的POJO(plain OLd JavaScript object),object只有逻辑,与框架无关,并防止$watch,$on,$broadcast的滥用;
demo其实是controller的一个实例,是$scope的一个对象,js里绑定到this上的model其实是绑定到$scope.demo上的;
Angular源码:
if (directive.controllerAs) { locals.$scope[directive.controllerAs] = controllerInstance; }
避免嵌套中父子重名问题,父子属性指代清晰
controller as也可在route中定义