数据双向绑定并不是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

模块模式是一个设计模式,它能够消除大量重复的 thisprototype使用。 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

  1. 安装NodeJS
  2. 安装Express: $ npm install -g express-generator
  3. 创建网站: $ express myApp
  4. 运行App准备:` cd myApp && npm install -d
  5. 运行App: `$ node app.js
  6. 高级运行App (源代码的改动触发重新编译):

    $ npm install --save-dev node mon

    $ nodemon app.js

( 本文版权属于© 2015 卓逸天成 | 转载请注明作者和出处:卓逸知识文库 )

深入探索AngularJS的更多相关文章

  1. 深入探索AngularJS(持续更新)

    数据双向绑定并不是Angular最出彩的地方.大部分对AngularJs的介绍都偏重于使用,使用的学习只是学了AngularJs的API,而那只能AngularJs的很小一部分.随着使用越来越深,系统 ...

  2. angularjs $http提交数据探索

    前两天在搞自己的项目,前端js框架用的是angularjs框架:网站整的差不多的时候出事了:那就是当我用$http.post()方法向服务器提交一些数据的时候:后台总是接收不到数据: 于是采用了其他方 ...

  3. (转)构建自己的AngularJS,第一部分:Scope和Digest

    原翻译链接:https://github.com/xufei/Make-Your-Own-AngularJS/edit/master/01.md 原文链接:http://teropa.info/blo ...

  4. [译]用AngularJS构建大型ASP.NET单页应用(一)

    原文地址:http://www.codeproject.com/Articles/808213/Developing-a-Large-Scale-Application-with-a-Single 渣 ...

  5. 走进AngularJs(一)angular基本概念的认识与实战

    一.前言 前端技术的发展是如此之快,各种优秀技术.优秀框架的出现简直让人目不暇接,作为一名业界新秀,紧跟时代潮流,学习掌握新知识自然是不敢怠慢.当听到AngularJs这个名字并知道是google在维 ...

  6. Angularjs 脏值检测

    文章转自:http://www.ituring.com.cn/article/39865 构建自己的AngularJS,第一部分:Scope和Digest 原文链接:http://teropa.inf ...

  7. angularjs(一)基础概念

    一.前言 前端技术的发展是如此之快,各种优秀技术.优秀框架的出现简直让人目不暇接,作为一名业界新秀,紧跟时代潮流,学习掌握新知识自然是不敢怠慢.当听到AngularJs这个名字并知道是google在维 ...

  8. AngularJs + Web API 页面开发(一)

    AngularJS这个JS框架是个神马东东我也不太清楚,我也是初学者~~ AngularJS适用于single page App,单页面程序都是局部刷新的,这一点和Ajax有第一的区别,因为使用Aja ...

  9. 走进AngularJs(三)自定义指令-----(上)

    一.有感而发的一些话 在学习ng之前有听前辈说过,angular上手比较难,初学者可能不太适应其语法以及思想.随着对ng探索的一步步深入,也确实感觉到了这一点,尤其是框架内部的某些执行机制,其复杂程度 ...

随机推荐

  1. myeclipse 上安装 Maven3

    myeclipse 上安装 Maven3   环境准备: JDK 1.6 Maven 3.0.4 myeclipse 8.6.1 安装 Maven 之前要求先确定你的 JDK 已经安装配置完成.Mav ...

  2. c#里如何实现讲一个字符串数组例如 “112,221”转化成两个字符串数组“112” “221” 中间以逗号隔开

    比如是S [0]="123,223" S[1]="111,222" ....... 想转化为 SX[0]="123" SX[1]=" ...

  3. python3版本main.py执行产生中间__pycache__详解

    __pycache__ 用python编写好一个工程,在第一次运行后,总会发现工程根目录下生成了一个__pycache__文件夹,里面是和py文件同名的各种 *.pyc 或者 *.pyo 文件. 先大 ...

  4. PL/SQL Developer 导出csv文件,用excel打开中文显示乱码

      用PL/SQL Developer的导出csv功能把sql语句的查询结果导出到一个csv文件.这个sql查询的结果里面有中文,最后用execel打开的时候发现中文全部是乱码. 方法 1 导出csv ...

  5. Linux系统下修改环境变量PATH路径

    方法一: PATH=$PATH:/etc/apache/bin 该方法只对当前会话有效,每次注销或者拿出系统,该设置就会无效 方法二: vi /etc/profile 在适当的位置写入:PATH=$P ...

  6. 第08章:MongoDB-CRUD操作--文档--删除

    ①语法 remove()  [2.6以后方法过时] deleteOne() [2.6以后官方推荐] deleteMany() [2.6以后官方推荐] db.collection.remove( < ...

  7. 20155205 2016-2017-2 《Java程序设计》第6周学习总结

    20155205 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 第十章 在Java中,输入串流代表对象为Java.io.InputStream实例,输出串流 ...

  8. 富文本粘贴word文档内容图片处理

    公司做的项目要用到文本上传功能. 网上找了很久,大部分都有一些不成熟的问题,终于让我找到了一个成熟的项目. 下面就来看看: 1.打开工程: 对于文档的上传我们需要知道这个项目是否符合我们的初衷. 运行 ...

  9. (转)ASP.NET(C#)FileUpload实现上传限定类型和大小的文件到服务器

    上传文件有两个主要的目的地,一个是服务器,另一个是数据库,ASP.NET内置了FileUpload这个上传控件,文本框显示用户选择的文件的全名. 其属性主要包括: ContenLength:上传文件大 ...

  10. java http大文件断点续传上传

    因为需要研究下断点上传的问题.找了很久终于找到一个比较好的项目. 效果: 上传中,显示进度,时间,百分比. 点击[Pause]暂停,点击[Resume]继续. 2,代码分析 项目进行了封装使用最简单的 ...