PS:Angularjs留存系列主要是用来记录一些自己在学习其他文章时觉得有必要留存一下的fortune!
文章可能会很长(默认每篇17个小的知识点),但是我们可以使用Ctrl + F 来查找啦!
1、AngularJS中,子作用域一般都会通过JavaScript原型继承机制继承其父作用域的属性和方法。但有一个例外:在directive中使用scope: { ... }
,这种方式创建的作用域是一个独立的"Isolate"作用域,它也有父作用域,但父作用域不在其原型链上,不会对父作用域进行原型继承。这种方式定义作用域通常用于构造可复用的directive组件。
作用域的原型继承是非常简单普遍的,甚至你不必关心它的运作。直到你在子作用域中向父作用域的原始类型属性使用双向数据绑定2-way data binding,比如Form表单的ng-model
为父作用域中的属性,且为原始类型,输入数据后,它不会如你期望的那样运行——AngularJS不会把输入数据写到你期望的父作用域属性中去,而是直接在子作用域创建同名属性并写入数据。这个行为符合JavaScript原型继承机制的行为。AngularJS新手通常没有认识到ng-repeat
、ng-switch
、ng-view
和ng-include
都会创建子作用域,所以经常出问题。 (见示例)
避免这个问题的最佳实践是在ng-model
中总使用.
,(至于为什么只要仔细体会JavaScript原型继承机制,我相信你就可以明白!!!)。。。参见文章always have a '.' in your ng-models。
比如:
<input type="text"ng-model"someObj.prop1">
优于:
"prop1" 如果你一定要直接使用原始类型,要注意两点:
2、
AngularJS存在四种作用域:(这篇文章讲得很好)
- 普通的带原型继承的作用域 --
ng-include
,ng-switch
,248)">ng-controller,directive withscope: true
;
- 普通的带原型继承的,并且有赋值行为的作用域 --
ng-repeat
,ng-repeat为每一个迭代项创建一个普通的有原型继承的子作用域,但同时在子作用域中创建新属性存储迭代项;
- “Isolate”作用域 -- directive with
scope: {...}
, 该作用域没有原型继承,但可以通过'=','@',和 '&'与父作用域通信。
- “transcluded”作用域 -- directive with
transclude: true
,它也是普通的带原型继承的作用域,但它与“Isolate”作用域是相邻的好基友。
每当一个指令被创建的时候,都会有这样一个选择,是继承自己的父作用域(一般是外部的Controller提供的作用域或者根作用域($rootScope)),还是创建一个新的自己的作用域,当然AngularJS为我们指令的scope参数提供了三种选择,分别是:false,true,244)">{};默认情况下是false。
(1)、当我们将scope设置为true的时候,我们就新创建了一个作用域,只不过这个作用域是继承了我们的父作用域;我觉得可以这样理解,我们新创建的作用域是一个新的作用域,只不过在初始化的时候,用了父作用域的属性和方法去填充我们这个新的作用域。它和父作用域不是同一个作用域。
(2)、当我们将false的时候,我们创建的指令和父作用域(其实是同一个作用域)共享同一个model模型,所以在指令中修改模型数据,它会反映到父作用域的模型中。
这是一篇对指令的Scope讲得很透彻的文章,也有相应的Demo参考! 强烈推荐对Directive的Scope有疑惑的同学去阅读学习下!
如果AngularJS总是将我们的代码wrap到一个function中并传入$apply(),以此来开始一轮$digest循环,那么什么时候才需要我们手动地调用方法呢?实际上,对此有着非常明确的要求,就是它只负责对发生于上下文环境中的变更会做出自动地响应(即,在方法中发生的对于models的更改)。的built-in指令就是这样做的,所以任何的model变更都会被反映到view中。但是,如果你在AngularJS上下文之外的任何地方修改了model,那么你就需要通过手动调用$apply()来通知AngularJS。
你总是应该使用接受一个作为参数的方法。这是因为当你传入一个到中的时候,这个会被包装到一个try…catch块中,所以一旦有异常发生,该异常会被$exceptionHandler service处理。
$digest循环会运行多少次?
答案是$digest循环不会只运行一次。在当前的一次循环结束后,它会再执行一次循环用来检查是否有models发生了变化。这就是脏检查(Dirty Checking),它用来处理在listener函数被执行时可能引起的model变化。因此,$digest循环会持续运行直到model不再发生变化,或者$digest循环的次数达到了10次。因此,尽可能地不要在listener函数中修改model。
Note: $digest循环最少也会运行两次,即使在listener函数中并没有改变任何model。正如上面讨论的那样,它会多运行一次来确保models没有变化。
5、AngularJS 之 Factory vs Service vs Provider
用Factory就是创建一个对象,为它添加属性,然后把这个对象返回出来。你把 service 传进 controller 之后,在 controller 里这个对象里的属性就可以通过 factory 使用了。
2)Service是用"new"关键字实例化的。因此,你应该给"this"添加属性,然后 service 返回"this"@H_301_463@。你把 service 传进 controller 之后,在controller里 "this" 上的属性就可以通过 service 来使用了。
3)Providers是唯一一种你可以传进 .config() 函数的 service。当你想要在 service 对象启用之前,先进行模块范围的配置,那就应该用 provider。
什么时候适合使用factory()方法
在service里面当我们仅仅需要的是一个方法和数据的集合且不需要处理复杂的逻辑的时候,factory()是一个非常不错的选择。
注意:需要使用.config()来配置service的时候不能使用factory()方法
什么时候适合使用service()方法
service()方法很适合使用在功能控制比较多的service里面
注意:需要使用.config()来配置service的时候不能使用service()方法
@H_792_502@
@H_792_502@@H_792_502@@H_792_502@什么时候适合使用provider()方法
当我们希望在应用开始前对service进行配置的时候就需要使用到provider()。比如,我们需要配置services在不同的部署环境里面(开发,演示,生产)使用不同的后端处理的时候就可以使用到了
当我们打算发布开源provider()也是首选创建service的方法,这样就可以使用配置的方式来配置services而不是将配置数据硬编码写到代码里面。
原文链接:https://www.f2er.com/angularjs/148887.html