一、AngularJS 初始化加载流程

1、浏览器载入HTML,然后把它解析成DOM。
2、浏览器载入angular.js脚本。
3、AngularJS等到DOMContentLoaded事件触发。
4、AngularJS寻找ng-app指令,这个指令指示了应用的边界。
5、使用ng-app中指定的模块来配置注入器($injector)。
6、注入器($injector)是用来创建“编译服务($compile service)”和“根作用域($rootScope)”的。
7、编译服务($compile service)是用来编译DOM并把它链接到根作用域($rootScope)的。
8、ng-init指令将“World”赋给作用域里的name这个变量。
9、通过{{name}}的替换,整个表达式变成了“Hello World”。

二、AngularJS Provider/Service/Factory

1、什么是 provider ?

provider 可以为应用提供通用的服务,形式可以是常量,也可以是对象。

比如我们在 controller 里注入进来的 $http, $scope 都可以认为是 provider。

1
2
3
4
5
app.controller('MainCtrl', function ($scope, $http) {
  $http.get(....).then(.....);
}

2、provider  

现在让我们自己来定制一个 provider

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
// 方法 1
$provide.provider('test', {
   n:1;
   $get: function () {
      return n;
    };
});
// 方法 2
$provide.provider('test', function () {
   this.n = 2;
   this.$get = function () {
   return n;
};
});
// 使用
app.controller('MainCtrl', function ($scope, test) {
    $scope.test = test;
});

  

让我们看看 provider 的内部实现代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function provider(name, provider_) {
  if (isFunction(provider_)) {
      provider_ = providerInjector.instantiate(provider_);
  }
   if (!provider_.$get) {
       throw Error('Provider ' + name + ' must define $get factory method.');
   }
   return providerCache[name + providerSuffix] = provider_;
}

可以看到 provider 的基本原则就是通过实现 $get 方法来进行单例注入,使用时获得的就是 $get 执行后的结果。

3、factory

那如果每次都要写一个 $get 是不是很麻烦? OK,所以我们有了 factory。 factory 可以说是 provider 的变种, 方法中的第二个参数就是 $get 中的内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 定义 factory
$provide.factory('dd', function () {
   return new Date();
});
// 使用
app.controller('MainCtrl', function ($scope, dd) {
    $scope.mydate = dd;
});

  

factory 的实现源代码:

1
2
3
4
5
6
7
8
9
function factory(name, factoryFn) {
 return provider(name, {
   $get: factoryFn
});
}

  

4、service

在 factory 的例子中我们还是需要 new 一个对象返回,而 service 就更简单了,这一步都帮你省了, 他的第二个参数就是你要返回的对象类, 也就是 new 的哦给你工作都不用你做了。够清爽吧?

// 定义 service

$provide.service('dd', Date);

下面是 service 的实现源代码:

1
2
3
4
5
6
7
8
function service(name, constructor) {
  return factory(name, ['$injector', function($injector) {
       return $injector.instantiate(constructor);
   }]);
}

然后 factory 和 service 带来代码精简的同时也损失了一些特性。 provider 定义的服务是可以通过模块 config 来配置的。

三、AngularJS 动态添加元素和删除元素

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
$scope.userName='Welcome to Angular World!';
$scope.test = function test(){
console.log('Angular 动态添加元素');
}
//通过$compile动态编译html
var html="<div ng-click='test()'>}</div>";
var template = angular.element(html);
var mobileDialogElement = $compile(template)($scope);
angular.element(document.body).append(mobileDialogElement);
// remove移除创建的元素
var closeMobileDialog = function () {
if (mobileDialogElement) {
  mobileDialogElement.remove();
}

四、AngularJS 事件广播与接收 

发送消息: $scope.$emit(name, data) 或者 $scope.$broadcast(name, data);

接收消息: $scope.on(name,function(event,data){ });

区别: $emit 广播给父controller   $broadcast 广播给子controller

broadcast 是从发送者向他的子scope广播一个事件。

这里就是ParentController发送, ParentController 和 ChildController 会接受到, 而MainController是不会收到的

$emit 广播给父controller,父controller 是可以收到消息

$on 有两个参数function(event,msg)  第一个参数是事件对象,第二个参数是接收到消息信息

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
angular.module('onBroadcastEvent', ['ng'])
     .controller('MainController', function($scope) {
       $scope.$on('To-MainController', function(event,msg) {
         console.log('MainController received:' + msg);
       });
     })
     .controller('ParentController', function($scope) {
       $scope.click = function (msg) {
         $scope.$emit('To-MainController',msg + ',from ParentController to MainController');
         $scope.$broadcast('To-ChildController', msg + ',from ParentController to ChildController');
         $scope.$broadcast('To-BrotherController', msg + ',from ParentController to BrotherController');
       }
     })
     .controller('ChildController', function($scope){
       $scope.$on('To-ChildController', function(event,msg) {
         console.log('ChildController received:' + msg);
       });
     })
     .controller('BrotherController', function($scope){
       $scope.$on('To-BrotherController', function(event, msg) {
         console.log('BrotherController received:' + msg);
       });
     });

五、AngularJS Promise Deferred实例

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
var app = angular.module('app', ['autocomplete']);
app.factory('Suggestion',
function($http, $q, $timeout){
  var suggestion = new Object();
  suggestion.getData = function(keyword) {
    var deferred = $q.defer();
    $http.get('http://codesearch.sinaapp.com/search.php',
    }).success(function(data){
      deferred.resolve(data);
    });
    return deferred.promise;
  }
  return suggestion;
});
app.controller('MySuggestionCtrl',
function($scope, $sce,Suggestion){
  $scope.autoComplete = function(keyword){
    if(keyword){
        Suggestion.getData(keyword).then(function(data){
        var dataList = data.split('|');
        $scope.dataList = dataList;
      });
    }
  }
});

 多个Promise实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var data2="222";
var promises = [];
var deffered1  = $q.defer();
var deffered2  = $q.defer();
$timeout(function(){
  deffered1.resolve(data1);
},2000);
$timeout(function(){
  deffered2.resolve(data2);
},2000);
promises.push(deffered1.promise);
promises.push(deffered2.promise);
 $q.all(promises).then(function(data){
    console.log(data);
});

输出: ["111", "222"] 这个一个数组对象顺序与push的顺序一致

  

六、AngularJS 全局scope与Isolate scope通信

一、scope作用域

1、AngularJS中,子作用域一般都会通过JavaScript原型继承机制继承其父作用域的属性和方法。但有一个例外:在directive中使用scope: { ... },这种方式创建的作用域是一个独立的"Isolate"作用域,它也有父作用域,但父作用域不在其原型链上,不会对父作用域进行原型继承。这种方式定义作用域通常用于构造可复用的directive组件.

2、如果我们在子作用域中访问一个父作用域中定义的属性,JavaScript首先在子作用域中寻找该属性,没找到再从原型链上的父作用域中寻找,如果还没找到会再往上一级原型链的父作用域寻找。在AngularJS中,作用域原型链的顶端是$rootScope,JavaScript寻找到$rootScope为止.

3、scope: { ... } - directive创建一个独立的“Isolate”作用域,没有原型继承。这是创建可复用directive组件的最佳选择。因为它不会直接访问/修改父作用域的属性,不会产生意外的副作用。

二、Isolate scope 引用修饰符

1、 = or =attr “Isolate”作用域的属性与父作用域的属性进行双向绑定,任何一方的修改均影响到对方,这是最常用的方式;

2、 @ or @attr “Isolate”作用域的属性与父作用域的属性进行单向绑定,即“Isolate”作用域只能读取父作用域的值,并且该值永远的String类型;

3、 & or &attr “Isolate”作用域把父作用域的属性包装成一个函数,从而以函数的方式读写父作用域的属性,包装方法是$parse

三、directive 与 controller 数据传递和通信

1、父controller监听全局scope(父scope)变量, 并广播事件给子scope(directive scope,每个directvie都有自己独立的scope作用域)

2、directive 定义本地scope,通过=、@、&(方法)字符显示引用全局scope

3、directive scope(子scope)通过parent[$scope.$parent.xxx]引用全局scope的属性

4、directive监听全局scope变量变化,可以通过$scope.$parent.$watch方法

四、实例讲解

http://www.cnblogs.com/hubcarl/p/4202053.html

七、AngularJS $apply vs $digest

  • $apply会使ng进入$digest cycle, 并从$rootScope开始遍历(深度优先)检查数据变更。
  • $digest仅会检查该scope和它的子scope,当你确定当前操作仅影响它们时,用$digest可以稍微提升性能。
  • 一些不必要的操作,放到$timeout里面延迟执行。
  • 如果不涉及数据变更,还可以加上第三个参数false,避免调用$apply
  • directive中执行的$evalAsync, 会在angular操作DOM之后,浏览器渲染之前执行。
  • controller中执行的$evalAsync, 会在angular操作DOM之前执行,一般不这么用。
  • 而使用$timeout,会在浏览器渲染之后执行。
  • 对时间有要求的,第二个参数可以设置为0。
    1
    2
    3
    4
    5
    6
    $http.get('http://path/to/url').success(function(data){
      $scope.name = data.name;
      $timeout(function(){
        //do sth later, such as log
      }, 0, false);
    });

详细:https://github.com/atian25/blog/issues/5

八、AngularJS Directive 学习 实例

1、restrict 它限制directive为指定的声明方式。如果省略的话,directive将仅仅允许通过属性声明

E - 元素名称: <my-directive></my-directive>

A - 属性名: <div my-directive="exp"></div>

C - class名: <div class="my-directive:exp;"></div>

M - 注释 : <!-- directive: my-directive exp -->

2、dialog实例

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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<!DOCTYPE html>
  
<html ng-app="Dialog">
  
<head>
  
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  
  <title>directive-dialog</title>
  
  <meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
  
  <script src="../../sea-modules/angular/angularjs/1.1.5/angular.js"></script>
  
</head>
  
<body>
  
<div ng-controller="MyCtrl">
  
  <button ng-click="show=true">show</button>
  
  <dialog title="Hello }"
  
          visible="}"
  
          on-cancel="show=false;"
  
          on-ok="show=false;methodInParentScope();">
  
    <!--上面的on-cancel、on-ok,是在directive的isoloate scope中通过&引用的。
  
    如果表达式中包含函数,那么需要将函数绑定在parent scope(当前是MyCtrl的scope)中-->
  
    Body goes here: username:} , title:}.
  
    <ul>
  
      <!--这里还可以这么玩~names是parent scope的-->
  
      <li ng-repeat="name in names">}</li>
  
    </ul>
  
  </dialog>
  
</div>
  
<script type="text/javascript">
  
  var myModule = angular.module("Dialog", []);
  
  myModule.controller("MyCtrl", function ($scope) {
  
    $scope.names = ["name1", "name2", "name3"];
  
    $scope.show = false;
  
    $scope.username = "carl";
  
    $scope.title = "parent title";
  
    $scope.methodInParentScope = function() {
  
      alert("scope里面通过&定义的东东,是在父scope中定义!!。。。");
  
    };
  
  });
  
  myModule.directive('dialog', function factory() {
  
    return {
  
      priority:100,
  
      template:['<div ng-show="visible">',
  
        '    <h3>}</h3>',
  
        '    <div class="body" ng-transclude></div>',
  
        '    <div class="footer">',
  
        '        <button ng-click="onOk()">OK</button>',
  
        '        <button ng-click="onCancel()">Close</button>',
  
        '    </div>',
  
        '</div>'].join(""),
  
      replace:false,
  
      transclude: true,
  
      restrict:'E',
  
      scope:{
  
        title:"@",//引用dialog标签title属性的值
  
        onOk:"&",//以wrapper function形式引用dialog标签的on-ok属性的内容
  
        onCancel:"&",//以wrapper function形式引用dialog标签的on-cancel属性的内容
  
        visible:"@"//引用dialog标签visible属性的值
  
      }
  
    };
  
  });
  
</script>
  
</body>
  
</html>

九、AngularJS 注意事项和问题总结(待续)

Beware that using  注意 angular.module('myModule', []) 与 angular.module('myModule') 的使用

angular.module('myModule', []) will create the module myModule and overwrite any existing module namedmyModule.

>>>angular.module('myModule', []) 创建一个新的module,覆盖已经存在的module

Use angular.module('myModule') to retrieve an existing module.

>>>angular.module('myModule') 指向已经存在的module

转自:http://www.cnblogs.com/hubcarl/p/4207909.html

AngularJS 初始化加载流程相关推荐

  1. Spring初始化加载流程分析

    关于Spring框架的介绍,网上有很多非常好的详细的文章,如果在本篇博客中没有了解到自己想要的东西,个人能力有限,只能使用博客记录一下自己目前了解的知识点了! 本篇博客将大致介绍一下Spring框架的 ...

  2. Spring Cloud Gateway系列【4】初始化加载流程源码解析

    文章目录 核心源码 Route类 AsyncPredicate接口 ServerWebExchange 接口 GatewayFilter RouteLocator RouteDefinitionLoc ...

  3. QT程序启动加载流程简介

    1. QT应用程序启动加载流程简介 1.1      QWS与QPA启动客户端程序区别 1.1.1   QWS(Qt Window System)介绍 QWS(Qt Windows System)是Q ...

  4. android内存加载dex,安卓8.1版本dex加载流程笔记--第一篇:oatfile,oatdexfile与dexfile...

    本帖最后由 L剑仙 于 2020-3-1 18:53 编辑 看雪发一遍了,在52再发一次 菜鸟最近初学脱壳,必须得先搞明白dex的加载流程,才能搞懂哪里到了脱壳的时机.n6装的8.1,最近跟了一遍8. ...

  5. iOS进阶之底层原理-应用程序加载(dyld加载流程、类与分类的加载)

    iOS应用程序的入口是main函数,那么main函数之前系统做了什么呢? 我们定义一个类方法load,打断点,查看栈进程,我们发现dyld做了很多事,接下来就来探究到底dyld做了什么. 什么是dyl ...

  6. 006-spring cloud gateway-GatewayAutoConfiguration核心配置-GatewayProperties初始化加载、Route初始化加载...

    一.GatewayProperties 1.1.在GatewayAutoConfiguration中加载 在Spring-Cloud-Gateway初始化时,同时GatewayAutoConfigur ...

  7. spring启动加载流程

    上次看了spring的加载流程,今天发现或多都忘记了,今天又看了一下,顺便总结一下: 标题spring的web项目启动: 1.首先web容器(比如Tomcat)会读取配置在web.xml中的监听器,从 ...

  8. Android6.0 keyguard锁屏加载流程分析

    锁屏界面的加载通常在android中有两种方式触发:android系统开机和screenOff(灭屏)后,再screenOn; 先来看 android系统开机时候的锁屏加载流程: 首先在系统启动过程中 ...

  9. Android之Launcher分析和修改4——初始化加载数据

    上面一篇文章说了Launcher是如何被启动的,Launcher启动的过程主要是加载界面数据然后显示出来, 界面数据都是系统APP有关的数据,都是从Launcher的数据库读取,下面我们详细分析Lau ...

最新文章

  1. 庐山真面-Oxite的HelloWorld
  2. js设置和清除cookie
  3. 20160818_周报日志之二
  4. 荣耀变鸿蒙系统,鸿蒙系统首批升级机型曝光!荣耀手机遗憾缺席,原因很简单...
  5. 5分钟了解阿里时序时空数据库
  6. linux 内核内核签名_24岁生日快乐,Linux内核
  7. 拿下阿里投资 回血的网易云音乐能成功突围吗?
  8. echarts-formatter
  9. Swift去除两边的特定字符(空格或其它)
  10. python全局代理_玩Python之HTTP代理
  11. 通过解析器向DNS服务器发出查询
  12. 数学分析思维导图整理(四)单变量积分学
  13. 音轨分离软件 Spleeter 使用教程及踩过的坑
  14. SpringBoot集成mybatis拦截器修改表名
  15. ubuntu系统计算机_显卡-性能测试软件
  16. FindBugs错误描述
  17. 《黑马程序员Android移动应用基础教程》学习笔记(1)
  18. switch c语言格式,switch语句格式是什么
  19. oracle sqlnet配置,sqlnet.ora文件配置详解
  20. Python最佳学习路线图

热门文章

  1. 服务器架构之性能扩展-第七章(8)
  2. 线性表 ----链表的C语言实现
  3. vue + axios---封装一个http请求
  4. HDU_1087-Super Jumping! Jumping! Jumping!
  5. 第四节 莎士比亚模板
  6. MySQL 性能优化,优化设计及设计原则解读
  7. Eclipse 代码自动提示的设置
  8. Zend Studio 12 windows 无限期试用
  9. Redis设计与实现阅读总结(二)单机数据库的实现
  10. ES6的几个实用技巧,你了解吗?