月度归档:2013年10月

(转)AngularJs学习笔记 全部–Guide教程系列文章索引

     在很久很久以前,一位前辈向我推荐AngularJs。但当时我没有好好学习,仅仅是讲文档浏览了一次。后来觉醒了……于是下定决心好好理解这系列的文档,并意译出来(英文水平不足……不能说是翻译,有些实在是看不懂,希望大家在参观的过程中指出其中的错误)。经过1个多月断断续续的努力,终于把Guide里面的文章基本上都弄出来。Guide中的部分章节,由于重复的部分似乎有点多,而且篇幅较短,这里就没有列出来。
  文章列表如下:
    By Lcllao.

(转)AngularJs学习笔记 3–concepts(概念)

一、总括
本文主要是angular组件(components)的概览,并说明他们如何工作。列表如下:
  1. statup – 依旧是hello world…改为Hello Kitty!
  2. runtime – 介绍angular的runtime
  3. scope – view与contorller的纽带(神马glue…胶)
  4. controller – app的行为(application behavior)
  5. model – app的数据
  6. view – 用户所看到的东东
  7. directives – HTML的语法扩展
  8. filters – 根据用户的本地格式,格式化数据
  9. injector – 加载我们的app(依赖管理之类)
  10. module – 配置injector
  11. $ – angular的命名空间(namespace)
二、启动(Startup)
下面描述angular是如何启动的(参考图表与下面的例子):
1. 浏览器加载HTML,将HTML标签转换为DOM对象;
2. 浏览器加载angular.js的脚本;
3. Angular等待DOMContentLoaded事件;
4. Angular寻找ng-app这个用于指定应用边界范围的directive;
5. 如果ng-app有指定module(也许是ng-app=”SomeApp”),将被用作配置$injector;
6. $injector用于创建$compile服务(service)以及$rootScope;
7. $compile服务用作“编译”(有点像遍历,然后做一点神秘的事情)DOM,并将其与对应的$rootScope连
接。
8. ng-init 这个directive在对应的scope中创建name属性并对其赋予”Kitty”值;
9. 将“{{name}}”的值插入(interpolates)到表达式中,最终显示”Hello Kitty!”。
2012090500475480

<!DOCTYPE html>

<html lang="zh-cn" ng-app>

<head>

    <meta charset="UTF-8">

    <title>Hello Kitty!</title>

    <style type="text/css">

        .ng-cloak {

            display: none;

        }

    </style>

</head>

<body>

<div ng-init="name='Kitty'">Hello {{name}}!</div>

<script src="../angular-1.0.1.js" type="text/javascript"></script>

</body>

</html>

三、Runtime
2012090601163790
  这图表和后面的例子,描述了angular如何通过浏览器event-loop(所有的时间处理函数,以及timer执行的函数,会排在一个queue结构中,利用一个无限的循环,不断从queue中取出函数来执行,这个就是event-loop。来自http://wiki.nodejs.tw/nodejs_from_scratch/javascript-yunodejs/2-1-event-loop)来进行交互。
  1. 浏览器event-loop等待事件到来。事件来自于用户交互(DOM events)、timer事件(setTimeout)、network事件(服务端响应,XHR之类);
  2. 事件回调函数开始执行。这里进入javascript上下文(context)。这回调函数可以修改DOM结构。
  3. 当回调函数执行完毕后,浏览器退出javascript context,根据DOM的改变来重绘视图。
  Angular通过创建自己的事件处理循环(event processing loop),修改了一般的javascript流(flow)。这将Javascript分割成传统的和Angular的执行上下文(execution context)。只要是在Angularexecution context 里面执行的操作,都拥有angular data-binding、异常处理(exception handling)、属性监视(property watching)等能力。我们可以通过在javascript使用$apply(),进入Angularexecution context。但要记住一点,在大多数(angular的)地方(如controllers、services),处理事件的directive会为你调用$apply。手动调用$apply的场景,一般是当你实现自定义事件处理函数,或者处理第三方库的回调的时候。
  1. 通过调用scope.$apply(stimulusFn)进入angular execution context。stimulusFn就是我们想在angular execution context中执行的函数(含scope作为参数)或者angular合法的表达式。
  2. Angular执行stimulusFn,这通常会改变应用的状态(application state)。
  3. Angular进入$digest loop。这个loop由一个处理$evalAsync queue 和处理$watch list两个更小的循环组成。$digest loop会在model稳定之前保持迭代,即$evalAsync queue为空,而且$watch list没有检测到任何变化。
  4. $evalAsync queue被用作安排必须跳出当前堆栈帧(堆栈帧指的是在堆栈中为当前正在运行的函数分配的区域(或空间)。传入的参数、返回地址(当这个函数结束后必须跳转到该返回地址。译注:即主调函数的断点处)以及函数所用的内部存储单元(即函数存储在堆栈上的局部变量)都在堆栈帧中。http://book.51cto.com/art/200804/70915.htm C.1.1  堆栈帧)之外,但在浏览器视图绘制之前的工作。这通常是通过使用setTimeout(0)来实现。但setTimeout(0)这方法,会导致缓慢,或者在每个事件处理完毕后,浏览器绘制视图时,出现视图闪烁(angular有没有去解决这个问题?如何解决?)。
  5. $watch list是有可能在最近一次迭代中被修改的表达式的集合。如果(model)发生了改变,那么$watch 函数会被调用,从而达到对特定的DOM重新赋值的目标。
  6. 一旦Angular $digest loop 完成了(之前3提到的情况),离开angular和javascript的context后,浏览器紧跟着就会去重绘DOM,以响应变化。
  下面解释例子“Hello Kitty”(-_-!)是如何在用户在文本框输入文本时实现数据绑定(data-binding)效果。
  1. 编译阶段(compilation phase):
    a) ng-model和input directive在<input>中版定keydown事件监听器。
    b) {{name}}占位符(interpolation,不知道怎么翻译)(表达式)设置一个$watch以便在name发生改变时有所响应。
  2. 执行阶段(runtime phase):
    a) 在inut控件中按下”X”按钮,让浏览器触发一个keydown事件;
    b) input directive捕捉到文本框值的改变,然后调用$apply(“name = ‘X’;”),在angular execution context中更新应用的model。
    c) Angluar将 “name = ‘X’;”应用在model中。(model发生改变)
    d) $digest loop开始
    e) $watch list检测到name的值被改变了,然后再次解析{{name}}表达式,然后更新DOM。
    f) Angulart退出(angular) execution context,再依次退出keydown事件以及javascript execution context;
    g) 浏览器重绘视图,更新字符。

&lt;!DOCTYPE html&gt;

&lt;html lang="zh-cn" ng-app&gt;

&lt;head&gt;

    &lt;meta charset="UTF-8"&gt;

    &lt;title&gt;Hello Kitty!&lt;/title&gt;

    &lt;style type="text/css"&gt;

        .ng-cloak {

            display: none;

        }

    &lt;/style&gt;

&lt;/head&gt;

&lt;body&gt;

    &lt;input ng-model="name"/&gt;

    &lt;p&gt;Hello {{name}}!&lt;/p&gt;

&lt;script src="../angular-1.0.1.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;/body&gt;

&lt;/html&gt;

四、Scope
  scope的是负责检测model的变化,并作为表达式的执行上下文(execution context)。Scope是在一个类似于DOM结构的层次结构中嵌套的(据之前了解,划分可能跟controller有关)。(详情查看individualdirective documentation,看看哪个directive会创建新的scope)
  下面的例子展示”name”这个表达式的值是根据它依赖(所属)的scope决定的,而且还包含了值查找的方式(类似Js的作用域链,自己没有就找老爸要)。

&lt;!DOCTYPE HTML&gt;

&lt;html lang="zh-cn" ng-app&gt;

&lt;head&gt;

    &lt;meta charset="UTF-8"&gt;

    &lt;title&gt;scope&lt;/title&gt;

    &lt;style type="text/css"&gt;

        .ng-cloak {

            display: none;

        }

    &lt;/style&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;div ng-controller="ControllerA"&gt;

    Hello {{name}}!;

&lt;/div&gt;

&lt;div ng-controller="ControllerB"&gt;

    Hello {{name}}!;

    &lt;div ng-controller="ControllerC"&gt;

        Hello {{name}}!;

        &lt;div ng-controller="ControllerD"&gt;

            Hello {{name}}!;

        &lt;/div&gt;

    &lt;/div&gt;

&lt;/div&gt;

&lt;script src="../angular-1.0.1.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;

    function ControllerA($scope) {

        $scope.name = 'Kitty';

    }

    function ControllerB($scope) {

        $scope.name = 'Lcllao';

    }

    function ControllerC($scope) {

        $scope.name = 'Jeffrey';

    }

    function ControllerD($scope) {

    }

&lt;/script&gt;

&lt;/body&gt;

&lt;/html&gt;

五、Controller
2012090701063773

&lt;!DOCTYPE HTML&gt;

&lt;html lang="zh-cn" ng-app&gt;

&lt;head&gt;

    &lt;meta charset="UTF-8"&gt;

    &lt;title&gt;Controller&lt;/title&gt;

    &lt;style type="text/css"&gt;

        .ng-cloak {

            display: none;

        }

    &lt;/style&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;div ng-controller="ControllerA"&gt;

    Hello {{name}}!

    &lt;button ng-click="doIt()"&gt;DoIt!!&lt;/button&gt;

&lt;/div&gt;

&lt;script src="../angular-1.0.1.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;

    function ControllerA($scope) {

        $scope.name = 'Kitty';

        $scope.doIt = function() {

            $scope.name = "Handsome";

        };

    }

&lt;/script&gt;

&lt;/body&gt;

&lt;/html&gt;

  Controller是在view背后的代码(-_-!)。它的职责是构建model,并通过回调函数,将其(model)推送到view中。View是当前scope到template(HTML)的映射(翻译得有点勉强…)。Scope是指挥model到view以及向controller发送event的纽带。
  Controller与view分离是很重要的,因为:Controller是写在javascript中的。Javascript是命令式的(imperative)。命令(imperative)是描述应用程序行为的一个好方法。Controller不应该包含任何显示信息(的逻辑)(DOM引用或者HTML片段),View模版是写在HTML里的。HTML是声明式的。声明式(的HTML)是描述UI的好方法。View不应该包含任何行为。由于Controller不知道自己需要对应哪一个View,使得一个Controller可以(间接)使用多个View。这对于re-skinning(更换皮肤?)、其他设备特定的视图(例如手机与桌面)还有代码的可测性是很重要的。
六、Model
2012090716235049
  Model,可以理解为数据对象。它被用作与模版结合,以产生视图。为了将model写入到视图中,model必须被scope所引用。与很多其他框架不一样,angular对model没有任何限制与要求。不需要额外添加class,也不需要通过特殊的特权方法去访问或者改变model。Model的数据类型,可以是原始的类型(string、number……),可以是键值对象({a:1,b:2}),也可以是函数(function() {…})。简要地说,angular的model只需要是一个普通的javascript对象。
七、View
  view是用户所能看到的东西。view诞生于模版。它与model结合,最终呈现为浏览器DOM。Angular采取一个对于其他很多模版系统来说,很不一样的方式去呈现View。
2012090717415747
       其他模版引擎:很多模版引擎,是通过建立带有特殊标记的HTML字符串来实现的。通常这些模版标记破坏了HTML的语法,这意味着不能通过一般的HTML编辑器去编辑代码(这个嘛…)。模版字符串传入模版引擎,与数据合并。最终生成HTML字符串。这些字符串一般通过.innerHTML的方式写入DOM中,促使浏览器呈现模版内容。当数据发生改变时,这个过程需要一次又一次地重复。模版的粒度与DOM更新的粒度一致。这粒的关键,是模版系统处理字符串。
       Angular:Angular模版的不同之处,在于它是基于DOM的而不是基于字符串的。模版依然需要在HTML中写入一些字符串,但依旧是HTML(不是通过在里面嵌入模版)。浏览器把HTML转换为DOM,然后DOM成为了compiler(angular的模版引擎)的输入。Compiler查找directives,依次在model中设置watches。得出的结果,是一个一直更新的view,不需要重新拼接model与template。model成为了view的唯一数据来源(single source of truth)。
 八、Directives
  Directive是一个行为(例如之前文章的例子“躲猫猫”)或DOM转换(自定义标签,里面包含一组DOM),将其名称放在属性、标签名、class名里面都可以触发该directive。Directive允许你以声明的方式扩展HTML的标签。
  下面的例子,还有一些疑问。就是$render如何触发@_@

&lt;!DOCTYPE HTML&gt;

&lt;html lang="zh-cn" ng-app="myDirective"&gt;

&lt;head&gt;

    &lt;meta charset="UTF-8"&gt;

    &lt;title&gt;directive&lt;/title&gt;

    &lt;style type="text/css"&gt;

        .ng-cloak {

            display: none;

        }

    &lt;/style&gt;

&lt;/head&gt;

&lt;body ng-controller="MyCtrl"&gt;

&lt;div ng-model="content" contenteditable="true"&gt;My Little Dada&lt;/div&gt;

&lt;pre&gt;modelValue = {{content}}&lt;/pre&gt;

&lt;button ng-click="reset()"&gt;reset(change model)&lt;/button&gt;

&lt;script src="../angular-1.0.1.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;

    angular.module("myDirective",[])

            .directive("contenteditable",function() {

                return {

                    require:'ngModel',

                    link:function (scope, element, attr, ngModel) {

                        function setVal() {

                            ngModel.$setViewValue(element.text());

                        }

                        // veiw -&gt; model

                        element.bind("keyup",function() {

                            scope.$apply(setVal);

                        });

                        // model -&gt; view

                        ngModel.$render = function(val) {

                            console.log("render running");

                            element.html(val);

                        };

                        //init

                        setVal();

                    }

                }

            }

    ).controller("MyCtrl",function($scope) {

                $scope.reset = function() {

                        $scope.content = "My Little Dada";

                };

            });

&lt;/script&gt;

&lt;/body&gt;

&lt;/html&gt;

九、Filters
  Filters 扮演一个数据转换(格式化)的角色。通常他们是与地域有关的,不同地域也许会有不同的输出格式。他们在追随了Unix过滤器的精神与类似的语法:|  (pipe)

&lt;!DOCTYPE HTML&gt;

&lt;html lang="zh-cn" ng-app&gt;

&lt;head&gt;

    &lt;meta charset="UTF-8"&gt;

    &lt;title&gt;filter&lt;/title&gt;

    &lt;style type="text/css"&gt;

        .ng-cloak {

            display: none;

        }

    &lt;/style&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;div ng-init="list = ['百度B','搜狗S','360','3SB']"&gt;

    数字格式化: 1233211234567 -&gt; {{1233211234567|number}}&lt;br/&gt;

    数组过滤,然后通过json格式输出: &lt;input ng-model="myFilterText" type="text"/&gt;&lt;br/&gt;

    {{list|filter:myFilterText|json}}&lt;br/&gt;

&lt;/div&gt;

&lt;script src="../angular-1.0.1.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;/body&gt;

&lt;/html&gt;

 十、Modules and the Injector
2012090812215170
  Injector是一个服务定位器。每一个Angular应用,都会有一个单独的injector。Injector提供一个通过名称查找对象实例的途径。Injector会在内部cache中保持所有对象实例,所以重复调用相同的名称时,返回的都是同一个对象实例。如果对象不存在,那么它会请求实例工厂(instance factory)去创建一个新实例。
  Module是一个配置injector的实例工厂的方法,被称为”provider”。
    <span style="color: #333333;">// Create a module</span>

    var myModule = angular.module('myModule', [])

    // Configure the injector

    myModule.factory('serviceA', function() {

    return {

    // instead of {}, put your object creation here

    };

    });

    // create an injector and configure it from 'myModule'

    var $injector = angular.injector('myModule');

    // retrieve an object from the injector by name

    var serviceA = $injector.get('serviceA');

    // always true because of instance cache

    $injector.get('serviceA') === $injector.get('serviceA');//true

  但是injector的真正牛X的地方在于它可以用于调用方法和”instantiate” type。这个美妙的特性是允许method和types请求他们所依赖的资源,而不是寻找他们。
   <span style="color: #333333;"> // You write functions such as this one.</span>

    function doSomething(serviceA, serviceB) {

    // do something here.

    }

    // Angular provides the injector for your application

    var $injector = ...;

    ///////////////////////////////////////////////

    // the old-school way of getting dependencies.

    var serviceA = $injector.get('serviceA');

    var serviceB = $injector.get('serviceB');

    // now call the function

    doSomething(serviceA, serviceB);

    //上面是传统的老方法~下面是angular说自己的牛X方法

    ///////////////////////////////////////////////

    // the cool way of getting dependencies.

    // the $injector will supply the arguments to the function automatically

    $injector.invoke(doSomething); // This is how the framework calls your functions

  注意,我们唯一需要写的,就是我们的function,在function的arguments中列出方法依赖的资源即可!当angular调用function时,他会使用”call”方法,自动填充function agruments。
  留意下面的例子中是如何在constructor中列出依赖的。当ng-controller实例化controller时,将自动提供所依赖的资源。没有必要去创建、寻找、创建injector引用来加载依赖资源。

&lt;!DOCTYPE HTML&gt;

&lt;html lang="zh-cn" ng-app="timeExample"&gt;

&lt;head&gt;

    &lt;meta charset="UTF-8"&gt;

    &lt;title&gt;injector&lt;/title&gt;

    &lt;style type="text/css"&gt;

        .ng-cloak {

            display: none;

        }

    &lt;/style&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;div ng-controller="ClockCtrl"&gt;

    Current time is : {{time.now}}

&lt;/div&gt;

&lt;script src="../angular-1.0.1.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;

    angular.module("timeExample", []).factory("myClock", function ($timeout) {

        var time = {};

        (function tick() {

            time.now = new Date().toString();

            $timeout(tick, 1000);

        })();

        return time;

    });

    /**

     *

     * @param $scope

     * @param myClock 这里自动插入了依赖的myClock!!

     * @constructor

     */

    function ClockCtrl($scope,myClock) {

        $scope.time = myClock;

    }

&lt;/script&gt;

&lt;/body&gt;

&lt;/html&gt;

十一、Angular Namespace
为了防止名称冲突,angular会在object的名称中加入前缀$。请不要在代码中使用$前缀以避免冲突。(-_-!! )
转载目的:用于记录保存资料和学习,感谢原作者分享

(转)AngularJs学习笔记 2–html compiler

一、总括
  Angular的HTML compiler允许开发者自定义新的HTML语法。compiler允许我们对任意HTML元素或属性,甚至是新的HTML标签、属性(如<beautiful girl=”cf”></beautiful >)附加行为。Angular将这些附加行为称为directives。
  HTML有很多专门格式化静态文档的预定义HTML样式结构(可以告诉浏览器如何显示标记的内容)。假设某东东需要被居中,而我们不需要教浏览器如何去做(此处省略N字)。我们只需要简单地对需要居中的标签加入align=”center”即可。这就是声明式语言(declarative language)的牛X之处。
  但是声明式语言也有它的局限性,即你不能告诉浏览器如何处理在预定义范围外的语法。例如,我们不能很简单地告诉浏览器如何让文本在浏览器的1/3处对齐。所以,我们正需要一个让浏览器与时俱进,学学新语法的途径。
  Angular预先绑定了一些对构建应用有帮助的directives。我们也可以自己创建属于自己应用的独特的directives。这些directive扩展将成为我们自己的应用的“特定领域语言”(Domain Specific Language)。
  这些编译将仅仅发生在浏览器端,无须服务端或者预编译步骤。
二、Compiler
  Compiler作为Angular的一个服务(Service),负责遍历DOM结构,寻找属性。编译过程分成两个阶段:
  1. 编译(Compile):遍历DOM节点树,收集所有directives。返回结果是一个链接函数(linking function)。
  2. 链接(Link):将directives绑定到一个作用域(scope)中,创建一个实况视图(live view)。在scope中的任何改变,将会在视图中得到体现(更新视图);任何用户对模版的活动(改变),将会体现在scope model中(双向绑定)。这使得scope model能够反映正确的值。
  一些directives,诸如ng-repeat,会为每一个在集合(collection)中的元素复制一次特定的元素(组合)。编译和链接两个阶段,使性能得以提升。因为克隆出来的模版(template)只需要编译一次,然后为每一个集合中的元素进行一次链接(类似模版缓存)。
三、Directive
  Directive是一个行为,在编译过程中遇到特定的HTML结构时,它会被触发。Directives可以放置在元素的name、attribute、class甚至注释中。以下是几种引用ng-bind(一个内置directive)的方法:

&lt;span ng-bind="exp"&gt;&lt;/span&gt;

&lt;span&gt;&lt;/span&gt;

&lt;ng-bind&gt;&lt;/ng-bind&gt;

&lt;!-- directive: ng-bind exp --&gt;

  Directive只是一个当编译器在DOM中遇到时会执行的一个函数(function)。directive API文档中有详细讲解如何创建一个directive。
下面是一个样例,可以让一个元素跟你的鼠标玩躲猫猫……

&lt;!DOCTYPE html&gt;

&lt;html lang="zh-cn" ng-app="HideAnkSeek"&gt;

&lt;head&gt;

    &lt;meta charset="UTF-8"&gt;

    &lt;title&gt;躲猫猫&lt;/title&gt;

    &lt;style type="text/css"&gt;

        .ng-cloak {

            display: none;

        }

    &lt;/style&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;span wildcat&gt;一碰我就跑~~来点我啊~~&lt;/span&gt;

&lt;script src="../angular-1.0.1.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;script type="text/javascript"&gt;

    angular.module("HideAnkSeek", []).directive("wildcat", function ($document) {

        var maxLeft = 400,maxTop = 300;

        var msg = ["我闪~~", "抓我呀~~~", "雅蠛蝶~~", "噢耶~~", "你真逊~!","就差那么一点点了!","继续吧~~总有一天我会累的"];

        return function (scope, element, attr) {

            element.css({

                "position":"absolute",

                "border":"1px solid green"

            });

            element.bind("mouseenter", function (event) {

                element.css({

                    "left":parseInt(Math.random() * 10000 % maxLeft) + "px",

                    "top":parseInt(Math.random() * 10000 % maxTop) + "px"

                }).text(msg[parseInt(Math.random() * 10000 % msg.length)]);

            }).bind("click",function (event) {

                        element.text("噢My Lady Gaga。。。被你逮到了。。。");

                        element.unbind("mouseenter");

                    });

        };

    });

&lt;/script&gt;

&lt;/body&gt;

&lt;/html&gt;

  在任意元素中添加“wildcat”这个属性,将会使该元素拥有新的行为。就这样,我们教会了浏览器如何处理会躲猫猫的元素(放心,你不是在某个房间,你不会挂的-_-!)。我们通过这一途径扩展了浏览器的“词汇量”。对于任意一个熟悉HTML规则的人,这算是一个比较自然的方式。
四、理解视图(View)
  外面有许多模版系统,它们通常都通过模版字符串与数据进行连接,生成最终的HTML字符串,并将结果通过innerHTML属性写入某元素里。
2012090422474719
   这意味着任何数据发生改变时,都需要重新将数据、模版合并成字符串,然后当作innerHTML写回对应元素中。这里存在一些问题:(这里直译实在没法懂..唯有YY)假设有这么一个场景,模版里包含输入框。用户对在输入框进行输入,模版同步更新。普通模版通过innerHTML、字符串与数据连接的方式更新视图,这样会打断用户的输入,体验不好。
  Angular是与众不同的。Angular编译器(compiler)通过directives处理DOM,而不是通过处理字符串模版。处理结果是一个与scope model组合并生成实时模版的链接函数(linking function)。视图与scope model的绑定对我们来说是透明的。开发者无须为更新视图、model做任何动作。而且,因为没有使用innerHTML更新视图模版,所以用户输入不会被打断。此外,angular directives不仅可以绑定文本值,而且还可以是拥有行为的结构(behavioral constructs)。
2012090422482027
  Angular的这个处理方式,产生了一个稳定的DOM。这意味着在DOM元素的生命周期里,一直与某model的实例绑定着,这个关系不会发生改变。这也意味着代码可以保持对某DOM对象的引用,对其注册事件函数,并且这个引用不会被模版数据合并所销毁。
转载目的:用于记录保存资料和学习,感谢原作者分享

(转)AngularJs学习笔记 1–bootstrap

AngularJs学习笔记系列第一篇,希望我可以坚持写下去。本文内容主要来自 http://docs.angularjs.org/guide/ 文档的内容,但也加入些许自己的理解与尝试结果。
 
一、总括
 
本文用于解释Angular初始化的过程,以及如何在你有需要的时候对Angular进行手工初始化。
 
二、Angular <script> 标签
 
本例用于展示如何通过推荐的路径整合Angular,实现自动初始化。
 

&lt;!doctype html&gt;

&lt;html xmlns:ng="http://angularjs.org" ng-app&gt;

&lt;body&gt;

  ...

&lt;script src="angular.js"&gt;

&lt;/body&gt;

&lt;/html&gt;

 
  • 将sciprt标签放置于页面底部。这样做能避免因为加载angular.js而阻挡HTML的加载,从而降低应用的加载时间。我们可以在http://code.angularjs.org中获取到最新版本的angularJs。出于安全考虑,切勿在产品中直接引用这个地址来加载脚本。但如果仅仅是研究学习使用的话,直接连接也无妨。
  • 选择:angular-[version].js 是方便阅读的一个版本,适合日常开发、调试使用。
  • 选择:angular-[version].min.js 是压缩、混淆后的版本,适合最终产品使用。
  • 放置”ng-app”到应用的根节点中,如果你想让angular自动启动你的应用,通常可以放置于<html>标签中。
&lt;html

 ng-app&gt;

 
如果我们需要使用老派风格的directive语法”ng:”,那么我们需要加入一个xml-namespace到html标签中以“取悦”IE。(这个是一个历史原因,我们也不推荐使用ng:)
 
三、自动初始化
 
Angular会在DOMContentLoaded事件中自动初始化,Angular会找出由你通过ng-app这个directive指定的应用根节点。如果找到,Angular会做以下事情:
 
  • 加载与module相关的directive。
  • 创建应用相关的injector(依赖管理器)。
  • 以ng-app指定根节点,开始对DOM进行相关“编译”工作。换言之,可以将页面的其中一部分(非<html>)作为根节点,从而限制angular的作用范围。

&lt;!DOCTYPE HTML&gt;

&lt;html lang="zh-cn"&gt;

&lt;head&gt;

   

&lt;meta charset="UTF-8"&gt;

    &lt;title&gt;Bootstrap-auto&lt;/title&gt;

    &lt;style type="text/css"&gt;

        .ng-cloak {

            display: none;

        }

    &lt;/style&gt;

&lt;/head&gt;

&lt;body&gt;

    这里是ng-app外面的~~{{1+2}}

    &lt;div ng-app&gt;这里是ng-app里面~~~{{1+3*2}}&lt;/div&gt;

    &lt;script src="../angular-1.0.1.js" type="text/javascript"&gt;&lt;/script&gt;

&lt;/body&gt;

&lt;/html&gt;

 
      注:里面的”ng-cloak”,这个是用于在angular.js编译完成之前(对!没错!是编译完成之前,不是angularjs加载完成之前。所以,如果想很好地避免这个情况,最好的办法是优化应用的加载流程,或者结合css对未编译的模版进行处理。而由于那万恶的ie6、7不支持属性选择器,所以最好使用class=”ng-cloak”的方式。编译完成后,这个class或属性会被删除。)隐藏模版,避免在页面显示原模版。
 
四、手工初始化
 
如果我们想进一步控制初始化进程(例如你需要通过script loader加载angular.js或者在angular编译页面前做一些操作),那么我们可以用一个手工调用的启动方法去代替。
以下例子等同于使用ng-app这个directive:
 

&lt;!DOCTYPE HTML&gt;

&lt;html lang="zh-cn"&gt;

&lt;head&gt;

    &lt;meta charset="UTF-8"&gt;

    &lt;title&gt;Bootstrap-manual&lt;/title&gt;

    &lt;style type="text/css"&gt;

        .ng-cloak {

            display: none;

        }

    &lt;/style&gt;

&lt;/head&gt;

&lt;body&gt;

    这里是ng-app外面的~~{{1+2}}

    &lt;div id="rootOfApp"&gt;这里是ng-app里面~~~{{1+3*2}}&lt;/div&gt;

    &lt;script src="../angular-1.0.1.js" type="text/javascript"&gt;&lt;/script&gt;

    &lt;script type="text/javascript"&gt;

        angular.element(document).ready(function() {

            angular.bootstrap(angular.element(document.getElementById("rootOfApp")));

        });

    &lt;/script&gt;

&lt;/body&gt;

&lt;/html&gt;

 
就是说,我们的代码可以按照以下步骤编写:
1. 在页面和其他代码加载完成后,找到应用模版的根节点;
2. 调用angular.bootstrap,让angular去将模版编译为一个可执行的,双向绑定的应用!
 
转载目的:用于记录保存资料和学习,感谢原作者分享