数据双向绑定并不是Angular最出彩的地方。大部分对AngularJs的介绍都偏重于使用,使用的学习只是学了AngularJs的API,而那只能AngularJs的很小一部分。随着使用越来越深,系统越来越大,我们也越来越迷失,是时候深入AngularJs的实现来学习。因为AngularJs 2.0就要来了,由于2.0和1不兼容,基于API的学习不再有用,而内部实现的精华才能延续。其实,软件的很多技术也大都如此,冲走的是实现,留下的是思想。
深入探索AngularJS
作用域Scope是DOM和Directives交互的抽象
Scope是POJO对象
AngularJS只是往Scope中添加了很多“内部"属性,大部分以$开头,还有些以$$开头,两个$开头的属性一般不要使用。
Scope是上下文
应该看作是一个容器,保存着当前的上下文和上下文敏感的变量数据等
Scope继承树
- Scope总是和一个DOM元素联系起来
- Controller会创建一个新的Scope
- Directive有时候会创建一个新的Scope
- 其他情况会直接使用父级的Scope
- 如果不在ng-app内,没有任何相关的Scope
Scope附加功能
AngularJS往Scope中添加了一些属性
遍历功能
- $id
Scope的唯一id号 - $root
- $parent
- $$childHead
- $$childTail
- $$prevSibling
- $$nextSibling
正交功能
Element和Attribute
Directive可以定义为Element(标识)也可以定义为标识的属性。 更为强大的架构就是综合应用这两种功能,用属性定义来改变或增强原Element的功能。
模块模式 - Module Pattern
模块模式是一个设计模式,它能够消除大量重复的
this
和prototype
使用。 Angular Material就使用这个模式开发模块代码 Angular Material Coding Conventions and Guidelines
参考: http://toddmotto.com/mastering-the-module-pattern/
创建模块
(function(){
//code
})();
这里申明了一个函数,然后马上调用它自己,这也被称作立即执行函数表达式 (Immediately-Invoked Function Expression)。这个函数就创建了一个新的作用域(Scope),从而模拟了类似私有域的效果, 把大部分代码从全局作用域(Gloable Scope)中隔离出来。
创建新的作用域之后,我们需要把代码赋于命名空间。
var Module = ( function () {
//code
})();
这样,我们就在全局作用域中申明了 Module
,这样我们就可以任意调用它,甚至把它传给另外一个模块。
私有方法 - Private Method
Javascript所有的函数定义默认下都是全局的,而且Javascript也没有命名空间的概念,这两个缺陷使得Javascript很容易产生名称冲突。 模块模式可以帮助解决这些问题。
Javascript 本身不能够定义私有方法,但是我们可以使用模块模式模拟出私有方法的效果。
私有方法本质上是:你不希望外部用户调用执行的某个作用域内部的任何东西。特别是那些从服务器读取或回写的操作。
通过模块模式,我们可以如下隐藏私有方法:
var Module = (function(){
var privateMethod = function(){
//do something
};
})();
在新作用域内部申明的方法privateMethod
就很好的隐藏起来,任何外部试图调用privateMethod
都会导致错误。
理解返回 - Return
景点模块模式可以用 return
返回一个对象给模块,那些在该对象下声明的方法可以通过模块的命名空间来调用。
var Module = (function(){
return {
publicMethod:function(){
//code
}
};
})();
调用: Module.publicMethod();
这和标准方式定义的对象没有任何区别:
var myObj = {
defaults: { name: 'Hao Wang'},
publicMethod: function () {
console.log(this.defaults);
}
};
//调用
myObj.publicMethod();
当时标准方式的问题是,一些内部属性和方法都暴露出来了,不能隐藏(Javascript没有私有属性和方法)。 如上面例子中的defaults
就有可能被外部用户修改,导致不期望的行为。
Promise - 异步的承诺
Promise让异步调用看起来更像同步调用,从而很容易的取到返回值和捕获异常。
介绍
使用Promise我们可以在任何一个执行点捕获错误,然后忽略剩下的执行步骤。 这种流程控制来源于新的代码风格本身,无需额外的代码。 从而,我们可以很容易的组合多个函数功能并且异常以冒泡式的抛出,同时有维持异步运行的能力。
Promise自始自终都是异步运行,我们不用担心它会阻塞其它部分的代码运行。
Promise in Angular
Angular的事件循环(Event Loop)在$rootScope.$evalAsync阶段解析(Resolve)Promise,直到$digest运行循环结束。 我们和容易的把Promise的结果输出成视图,这能够直接把XHR调用的结果直接赋给$scope对象的一个属性。
使用Promise到后台取数据的一个实例
<ul ng-controller="DashboardController">
<li ng-repeat="pr in pullRequests">
{{pr.title}}
</li>
</ul>
当用服务返回一个promise, 我们可以用.then()
方法与promise进行交互操作, 我们可在该方法中修改scope中的任何变量,从而改变视图。
angular.module('myApp', [])
.controller('DashboardController', ['$scope', 'GithubService', function($scope, GithubService){
GithubService.getPullRequests(123) //这里返回的是Promise
.then(tunction(data){
$scope.pullRequests = data.data;
});
}]);
创建一个Promise
内建服务$q
可以用来创建你自己的Promise。我们可以通过调用$q.defer()
方法来创建一个“延迟”对象: var deferred = $q.defer();
“延迟”对象有三个方法和一个promise属性,该属性返回一个Promise对象。
-
.resolve(value)
- 解析(返回结果)方法 -
.reject(reason)
- 拒绝方法;等同于解析出一个拒绝对象.resolve($q.reject(reason));
-
.notify(value)
- 返回执行的状态方法
Promise执行状态
如果我们有一个长时间运行的请求,可以调用.notify()
来及时返回进程状态。 通常,我们会把这个长时间任务放在一个服务中:
.factory('GithubService', funcion($q, $http){
var getEventsFromRepo= function(){
//task
};
var service = {
makeMultipleRequests: function(repos){
for (var i=0; i < repos.length; i++) {
output.push(getEventsFromRepo(repos[i]));
percentComplete = (i+1) / repos.length * 100;
d.notify(percentComplete);
}
d.resolve(output);
return d.promise;
}
}
return service;
});
这里,每取一个repo, 我们就会收到一个进程状态的通知。下面是对这个Pomise的使用和状态通知的显示
.controller('HomeController', function($scope, GithubService){
GithubService.makeMultipleRequests(['auser/behavior','..'])
.then(function(result){
//Handle the result
}, function(err){
//Error occurred
}, function(percentComplete) {
$scope.progress=percentComplte;
});
});
异步流
Promise的then()方法返回一个新的Promise, 这个新的Promise实际上是在原始Promise的值解析之后创建的。这样我们就可以用then()让异步的执行通过一个一个Promise串联下去。
使用then()我们创建了异步执行体流,这样我们可以在任何一步切入,然后切换不同的返回值。 这种切换也可以染我们暂停或者延迟解析的流程。
$http服务就是使用这种切入来实现请求和响应的interceptors。
$q服务还有几个其他的帮助方法:
- $q.all(promises) - 可以把多个Promise合并成一个Promise。
- $q.defer() - 创建一个延迟对象。
- $q.reject(reason) - 创建一个Promise,其解析值为rejection
- $q.when(value) - 把一个对象封装成为Promise,这个对象可以是普通对象也可以原本就是Promise。
与服务器的交互
谈到后端时,我们有两种情况:有服务器后端和无服务器后端
ExpressJS作服务器后端
搭建Express
- 安装NodeJS
- 安装Express:
$ npm install -g express-generator
- 创建网站:
$ express myApp
- 运行App准备:` cd myApp && npm install -d
- 运行App: `$ node app.js
- 高级运行App (源代码的改动触发重新编译):
$ npm install --save-dev node mon
$ nodemon app.js
( 本文版权属于© 2015 卓逸天成 | 转载请注明作者和出处:卓逸知识文库 )
深入探索AngularJS(持续更新)的更多相关文章
-
BLE资料应用笔记 -- 持续更新
BLE资料应用笔记 -- 持续更新 BLE 应用笔记 小书匠 简而言之,蓝牙无处不在,易于使用,低耗能和低使用成本.'让我们'更深入地探索这些方面吧. 蓝牙无处不在-,您可以在几乎每一台电话.笔记本电 ...
-
( 译、持续更新 ) JavaScript 上分小技巧(三)
最近家里杂事较多,自学时间实在少的可怜,所以都在空闲时间看看老外写的内容,学习之外顺便翻译分享~等学习的时间充足些再写写自己的一些学习内容和知识点分析(最近有在接触的:复习(C#,SQL).(学习)T ...
-
( 译、持续更新 ) JavaScript 上分小技巧(一)
感谢好友破狼提供的这篇好文章,也感谢写这些知识点的作者们和将他们整理到一起的作者.这是github上的一篇文章,在这里本兽也就只做翻译,由于本兽英语水平和编程能力都不咋地,如有不好的地方也请多理解体谅 ...
-
【持续更新】JavaScript常见面试题整理
[重点提前说]这篇博客里的问题涉及到了了JS中常见的的基础知识点,也是面试中常见的一些问题,建议初入职场的园友Mark收藏,本文会持续更新~ 1. 引入JS的三种方式 1.在HTML标签中直接使用,直 ...
-
中国.NET:各地微软技术俱乐部汇总(持续更新中...)
中国.NET:各地微软技术俱乐部汇总(持续更新中...) 本文是转载文,源地址: https://www.cnblogs.com/panchun/p/JLBList.html by 史记微软. ...
-
BAT 前端开发面经 —— 吐血总结 前端相关片段整理——持续更新 前端基础精简总结 Web Storage You don&#39;t know js
BAT 前端开发面经 —— 吐血总结 目录 1. Tencent 2. 阿里 3. 百度 更好阅读,请移步这里 聊之前 最近暑期实习招聘已经开始,个人目前参加了阿里的内推及腾讯和百度的实习生招聘, ...
-
前端深入之js篇丨Array数组操作从入门到成神Up Up Up,持续更新中
写在前面 随着前端深入的不断学习,发现数组这个数据结构在前端中有着相当大的存在感,由于我初学前端的时候并没有系统性的学习数组,所以我将通过这篇文章同你一起学习数组,希望我们能一起进步,学会熟练操作数组 ...
-
iPadOS 更新日志 - 持续更新中
本文只是为了简单记录一下每个正式版本发布时间和更新内容,只有这个初衷,从2019年9月25日开始,将会持续更新. iPadOS 13.1 - 2019年9月25日 经全新命名的 iPadOS 是一款强 ...
-
iOS面试高薪,进阶 你会这些呢嘛?(持续更新中)
这个栏目将持续更新--请iOS的小伙伴关注!做这个的初心是希望能巩固自己的基础知识,当然也希望能帮助更多的开发者! 基础>分析>总结 面试 iOS常见基础面试题(附参考答案) iOS底层原 ...
随机推荐
-
Git版本控制管理学习笔记2--起步
首先确保系统中已经安装了git,这里使用的linux系统. 一.命令行初步使用: 1.git命令: 列出它的选项和最常用的子命令.标准命令格式中,COMMAND代表的就是下面列出的子命令. [root ...
-
你可能不知道的Google Chrome命令行参数
概述: 关于Google Chrome命令行参数(英文叫Google Chrome Command line switches),是Chrome为了实现实验性功能.方便调试. ...
-
支付SDK的安全问题——隐式意图可导致钓鱼攻击
该漏洞涉及到app所使用的intent和intent filter. intent是一个可用于从一个app组件请求动作或处理事件的“消息对象”.Intent负责对应用中一次操作的动作.动作涉及数据. ...
-
Summary: Merge Sort of Array &;&; 求逆序对
常用算法(后面有inplace版本): package ArrayMergeSort; import java.util.Arrays; public class Solution { public ...
-
让popUpWindow之外的区域显示阴影效果
/** * 让popupwindow以外区域阴影显示 * @param popupWindow */ private void popOutShadow(PopupWindow popupWindow ...
-
Windows2012 cannot access netapp CIFS share
NAS1> options cifs.smb2.signing.requiredcifs.smb2.signing.required off NAS1> options cifs.smb2 ...
-
HTTP、TCP、IP协议常见面试题
前言:在看面试题之前,先了解一下基本定义. HTTP.TCP.IP协议基本定义 HTTP: (HyperText Transport Protocol)是超文本传输协议的缩写,它用于传送WWW方式的数 ...
-
L1-029 是不是太胖了
据说一个人的标准体重应该是其身高(单位:厘米)减去100.再乘以0.9所得到的公斤数.已知市斤是公斤的两倍.现给定某人身高,请你计算其标准体重应该是多少?(顺便也悄悄给自己算一下吧……) 输入格式: ...
-
在64位系统上部署BDE的要点
首先,据我所知,Borland/CodeGear没有发布过支持64bit windows的BDE安装包,如果你在网上看到了相关的BDE安装包,很有可能是使用者自己重新打包发布的. 无论是在32bit ...
-
论坛模块_版块管理_增删改查&;实现上下移动
论坛模块_版块管理1_增删改查 设计实体Forum.java public class Forum { private Long id; private String name; private St ...