AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]转自:angularJS的工作原理转自:通过<script>标签引入到HTML中,那么此时Angular就做为一个普通的DOM节点等待浏览器解析当浏览器解析到这个节点时,

大家好,又见面了,我是你们的朋友全栈君。

转自:angularJS 的工作原理

转自:通过<script>标签引入到 HTML 中那么此时 Angular 就做为一个普通的 DOM 节点等待浏览器解析

当浏览器解析到这个节点时,发现它是一个 js 文件,那么浏览器会停止解析剩余的 DOM 节点,开始执行这个js(即angular.js)

同时 Angular 会设置一个事件监听器来监听浏览器的 DOMContentLoaded 事件

当 Angular 监听到 DOMContentLoaded 事件时,就会启动 Angular 应用

1. 初始化阶段

Angular 开始启动后,它会查找 ng-app 指令

然后初始化一系列必要的组件(即 $injector、$compile 服务以及 $rootScope),接着重新开始解析 DOM 树

2. 编译、链接阶段

$compile 服务通过遍历 DOM 树的方式查找有声明指令的 DOM 元素

当碰到带有一个或多个指令的 DOM 元素时,它会排序这些指令(基于指令的priority优先级)

然后使用 $injector 服务查找 和 收集指令的 compile 函数并执行它

每个节点的编译方法运行之后,$compile 服务就会调用链接函数。这个链接函数为绑定了封闭作用域的指令设置监控。这一行为会创建实时视图

最后,在$compile 服务完成后,AngularJS 运行时就准备好了

3. 运行阶段

Angular提供了自己的事件循环

指令自身会注册事件监听器,因此当事件被触发时,指令函数就会运行在 AngularJS 的 $digest 循环中

$digest 循环会等待 $watch 表达式列表

当检测到模型变化后,就会调用 $watch 函数,然后再次查看 $watch 列表以确保没有模型被改变

一旦 $digest 循环稳定下来,并且检测到没有潜在的变化了,执行过程就会离开 Angular 上下文并且通常会回到浏览器中,DOM 将会被渲染到这里

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

当你用浏览器去访问 index.html 的时候,angularJS 做了以下事情去渲染页面:

1. 加载 html,然后解析成 DOM
2. 加载 angular.js 脚本
3. AngularJS 等待 DOMContentLoaded 事件的触发
4. AngularJS 寻找 ng-app 指令,根据这个指令确定应用程序的边界
5. 使用 ng-app 中指定的模块配置$injector
6. 使用 $injector 创建 $compile 服务 和 $rootScope 
7. 使用 $compile 服务编译 DOM 并把它链接到 $rootScope 上
8. ng-init 指令对 scope 里面的变量 xxx 进行赋值
9. 对表达式 {{xxx}} 进行替换,于是乎,页面显示数据

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

  • angular 和浏览器进行交互,粗略来讲分为 3 个阶段:

1. 浏览器的事件回路一直等待着事件的触发,事件包括用户的交互操作、定时事件或者网络事件(如服务器的响应等)

2. 一旦有事件触发,就会进入到 Javascript 的 context 中,一般通过回调函数来修改 DOM

3. 等到回调函数执行完毕之后,浏览器又根据新的 DOM 来渲染新的页面

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

  • AngularJS 修改了一般的 Javascript 工作流,并且提供了它自己的事件处理机制

这样就把 Javascript 的 context 分隔成两部分

一部分是原生的 Javascript 的 context

另一部分是 AngularJS 的 context

只有处在 AngularJS 的 context 中的操作才能享受到 Angular 的 data-binding、exception handling、property watching 等服务

但是对于外来者(如原生的 Javascript 操作、自定义的事件回调、第三方的库等)Angular 也不是一概不接见

可以使用 AngularJS 提供的 $apply() 函数,将这些外来者包进 AngularJS 的 context 中,让 Angular 感知到他们产生的变化

1. 首先,浏览器会一直处于监听状态,一旦有事件被触发,就会被加到一个 event queue 中,event queue 中的事件会一个一个的执行

2. event queue 中的事件如果是被 $apply() 包起来的话,就会进入到 AngularJS 的 context 中,这里的 fn() 是我们希望在 AngularJS 的 context 中执行的函数

3. AngularJS 将执行 fn() 函数,通常情况下,这个函数会改变应用的某些状态

4. 然后 AngularJS 会进入到由两个小循环组成的 $digest 循环中

一个循环是用来处理 $evalAsync 队列的

用来 schedule 一些需要在渲染视图之前处理的操作,通常通过 setTimeout(0) 实现

速度会比较慢,可能会出现视图抖动的问题

一个循环是处理 $watch 列表的

是一些表达式的集合,一旦有改变发生,那么 $watch 函数就会被调用

$digest 循环会一直迭代知道 $evalAsync 队列为空并且 $watch 列表也为空的时候,即 model 不再有任何变化。

5. 一旦 AngularJS 的 $digest 循环结束,整个执行就会离开 AngularJS 和 Javascrip 的 context,紧接着浏览器就会把数据改变后的视图重新渲染出来

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

这段代码有了一个 input 来接收用户的输入

在用浏览器去访问这个 html 文件的时候,input上的 ng-model 指令会给 input 绑上keydown事件

并且会给 name 变量建立一个 $watch 来接收变量值改变的通知。

在交互阶段主要会发生以下一系列事件:

1. 当用户按下键盘上的某一个键的时候(比如说A),触发 input 上的 keydown 事件

2. input 上的指令察觉到 input 里值的变化,调用 $apply(“name=‘A’”) 更新处于 AngularJS 的 context 中的 model

3. AngularJS 将’A’赋值给 name

4. $digest 循环开始,$watch 列表检测到 name 值的变化,然后通知 {{name}} 表达式,更新 DOM

5. 退出 AngularJS 的 context,然后退出 Javascript 的 context 中的 keydown 事件

6. 浏览器重新渲染视图

AngularJS

Google 推出的开源的前端 JS 结构化框架,主体是 页面中的动态数据与内存的读取

相较于 jQuery

jQuery 是前端函数库,封装简化 DOM 操作

应用

构建单页面 SPA Web 应用____Single Page Application

将所有的活动局限于一个 html 页面 (即使页面跳转了,也是在本页面跳转)

当页面中有部分数据发生了变化,不会刷新整个页面,而是局部刷新

利用的就是 ajax 技术,路由

Web App 应用

饿了么微信网页版

后台管理应用: 阿里云、土豆后台、唯品会… …

特性:

双向数据绑定

声明式依赖注入

解耦应用逻辑, 数据模型和视图

完善的页面指令

定制表单验证

Ajax 封装

老版本 angular-1.2.xx

 

新版本 angular-1.5.xx

 

输入框的内容,实时显示到下方:

  • $(function(){
        $('input').keyup(function(){    // 不能使用 change,在失去焦点时触发
            $('span').html(this.value);
        });
    });
    
    /*************** angular-1.2***************/


    AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

    AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

<body ng-app>    是 <body ng-app=””> 的简写____指向创建模块的名字

angularJS 不必写一行 js 代码,即可实现,且速度更快

使用:(ng 是核心模块,其他都是功能扩展模块)

1. 引入 angular.js

<script src=’./js/angular-1.2.29/angular.js’></script>

2. ng-app 指令,通常 <body ng-app>____使用 插件 ng-inspector 进行数据查看

告诉 angular 核心,管理 当前标签 所包含的整个区域

并且自动创建 $rootScope 根作用域对象

3. 在管理的标签区域内使用 angularJS

ng-model    将当前输入框的值 与 xx 关联(属性名: 属性值),并且作为当前作用域对象 $rootScope 的属性

{{表达式}}    显示数据,从 当前作用域对象 $rootScope 的指定属性名上取

通常有一个返回值,可以放到任何需要的位置,

剖析: 

数据流向

页面上初始化时无数据____ng-model 是双向数据绑定

首先是从页面流向内存,再从内存流向页面的 angular 表达式 和 angular 指令

② 页面上初始化时有数据____ng-init=”username=’SunWuKong'”

ng-init 是单向数据绑定,从页面 view 流向 model 内存

{{表达式}} 也是单向数据绑定,从内存 model 流向 view 页面

下载: ng-inspector 插件打开的就是 angularJS 的 内存____最大的对象就是 $rootScope 

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

数据绑定:

数据从一个地方 A 移动(传递)到另一个地方 B____这个过程由框架去完成

双向数据绑定(视图 view <—-> model 模型)—- (网页 <—-> 内存)____页面主要就是 angular 指令 和 angular 表达式

数据可以从 view 流向 model,也可以从 model 流向 view

使用 ng-model 使得 页面 的数据存储到 内存

单向数据绑定

View–>Model  : ng-init

Model–>View  : {{表达式}} 去内存中获取数据,渲染到页面

依赖注入

依赖对象: 完成某个特定功能必须要某个对象才能实现____比如 定义子对象,必须形参 $scope

依赖注入: 依赖对象 以形参的形式 被注入进来使用____声明式依赖注入 (对应的一个叫 命令式依赖注入‘遍历指定数组每个元素’)

命令式 更注重过程 (解答题)

声明式 更注重结果,是对命令式的局部包装 (选择题)

又由于代码压缩,会改变 形参 的命名,所以必须使用 [“形参“, function(形参){…}] 显示声明依赖注入

MVC 模式

M: Model, 即模型, 储存数据的容器, 提供操作数据的方法

在 angular 中为 scope

V: View, 即视图, 显示 Model 的数据, 将数据同步到 Model, 与用户交互

在 angular 中为 页面,包括: html/css/directive/expression

C: Controller, 即控制器, 初始化 Model 数据, 为 Model 添加行为方法

在 angular 中为 angular 的 ng-controller

MVVM 模式

在 MVVM 中 angular 的 controller 不再是架构的核心

angular 的 controller 只是起辅助作用,用来辅助 $scope 对象,即 VM 层

M: Model, 即数据模型

在 angular 中为 scope 中的各个数据对象

V: View, 即视图

在 angular 中为 页面

VM: ViewModel, 即视图模型

在 angular 中为 scope 对象

根作用域对象

一个 js 实例对象,ng-app 指令会默认创建一个 根作用域对象 $rootSScope

作用域对象

根作用域对象的 属性和方法 与页面中的 指令/表达式 是关联的

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

控制器对象

用于控制 angularJS 应用数据的 实例对象

ng-controller 指定控制器构造函数____形参必须是 $scope____依赖注入

angular 会自动 new 这个构造函数创建控制器对象

同时 还会创建一个新的作用域对象 $scope ,  它是 $rootScope 的 (继承关系)子对象____$scope____作用域对象

(不可能用 ng-init 初始化所有对象)

  • API: ng/function/angular.module()____一个参数是获取,多个参数是创建

可以在全局位置创建、注册、获取 Angular 模块

所有模块都必须使用这个机制注册 才能在应用中生效

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

使用:

1. 创建模块对象        <body ng-app=”myApp”>____ng-app 指向创建模块的名字

var myModule = angular.module(“myApp”, []);

2. 生成作用域对象____取代 自定义构造函数

myModule.controller(“myController1”, function($scope){

$scope.empName = “SunWuKong”;

});

myModule.controller(“myController2”, function($scope){

$scope.empName = “ZhuBaJie”;

});

——————— 优化 ———————-链式调用 (返回值为 作用域对象)

angular.module(“myApp”, []).controller(“myController1”, function($scope){

$scope.empName = “SunWuKong”;

}).controller(“myController2”, function($scope){    // 隐式声明依赖注入

$scope.empName = “ZhuBaJie”;

});

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

注意:

js 代码压缩时,会改变形参,导致 angular 无法解析

解决: 显示声明依赖注入

angular.module(“myApp”, []).controller(“myController1”, [‘$scope‘, function($scope){

$scope.empName = “SunWuKong”;

}]).controller(“myController2”, [‘$scope‘, function($scope){

$scope.empName = “ZhuBaJie”;

}]);

  • {{表达式}}

单项数据绑定

如果是变量 会在作用域链中寻找变量 {{abc.split(“”).reverse().join(“”)}}____ 字符串反转

还可以是 {{123}}{{‘abc’}}{{true}}

{{null}}、{{undefine}}、{{NaN}}、{{Infinity}} 会被解析成 空串 “”,不显示任何内容 

  • 项目

一个项目下来,首先是 UI 设计页面效果  

UI 从 14 年开始火,比 美工 高一个档次  

然后前端工程师分析 UI 设计图,进行静态 html 页面设计 

接下来是,数据的动态展现,与后端交互

然后是用户的交互,数据的展现

angularJS 开发第一步就是 新建 ng-app=”myApp”

ng-controller 实现子作用域对象 $scope

ng-model 实现双向数据绑定

{{表达式}} 从内存显示数据到页面

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

  • 常用指令
  • 点击事件

<button ng-click=”getTotalPrice()>计算</button>

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

  • 遍历数组显示数据____数据有几个数组就会产生几个新的作用域

<div>

<h2>人员信息列表</h2>

<ul>

<li  ng-repeat=”person  in persons>

{{$index}} —- {{person.username}} —- {{person.age}}

{{$first}} —- 第一个 返回 true

{{$last}} —- 最后一个 返回 true

{{$odd}} —- 奇数返回 true,从 1 开始计算

{{$even}} —- 偶数返回 true,从 1 开始

</li>

</ul>

</div>

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂] 

  • ng-bind 指令 解决数据闪屏:由于用户网速不好,第一次打开页面会看到 {{表达式}}

浏览器引擎从上往下解析

因为浏览器还没有解析到引入的 angular.js,所以页面还没有生效,导致了 数据闪屏

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

<div>

<p>{{123}}</p>

优化为:

<p ng-bind=”123></p>

</div>

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

  • ng-show 布尔类型,如果为 true 则 显示
  • ng-hide 布尔类型,如果为 true 则 隐藏

<div>

<button ng-click=”switchLike()”>切换喜欢</button>

<p ng-show=”isLike>我喜欢刘亦菲</p>

<p ng-hide=”isLike>刘亦菲喜欢我</p>

</div>

——————- javascript ——————

$scope.isLike = true;

$scope.switchLike = function(){

$scope.isLike  = !$scope.isLike ;

};

—————————————- 控制 css 杨样式 ————————————————–

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

  • ng-style  动态引用 js 指定的的样式对象 {“color”:”blue”, “backgrouond”: “red”};

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

  • ng-mouseenter
  • ng-mouseleave

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

  • ng-class 动态引用定义的样式    {“aClass”: true, bClass: true};

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

 AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

字数统计,实时显示

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

  • <html>
        <head>
            <meta charset="UTF-8">
            <style type="text/css">
                textarea {
                    resize: none;
                }
            </style>
        </head>
        <body ng-app="myApp">
            <div ng-controller="MyCtrl" >
                <h2>个性签名:</h2>
                <textarea cols="30" rows="10" ng-model="words"></textarea>
                <div>
                    <button ng-click="saveWords()">保存</button>
                    <button ng-click="readWords()">读取</button>
                    <button ng-click="clearWords()">删除</button>
                </div>
                <p>剩余字数: <span ng-bind="getCount()"></span></p>
            </div>
            
            <script type="text/javascript" src="https://cdn.bootcss.com/angular.js/1.5.10/angular.js"></script>
            <script type="text/javascript">
                var limitLength = 100;    // 字数限制 100 字
                //window.onDOMContentLoaded = function(){    // 会报错 ---- 看上面的工作原理
                    angular.module("myApp", []).controller("MyCtrl", ["$scope", function($scope){ $scope.words = "哈哈"; $scope.getCount = function(){ $scope.wordsLength = limitLength - $scope.words.length; if($scope.words.length > 100){ // 超出字数限制,让用户输入失效 $scope.words = $scope.words.slice(0, limitLength); }; return $scope.wordsLength; }; $scope.saveWords = function(){ sessionStorage.setItem("session_key", JSON.stringify($scope.words)); console.log("已经保存到 sessionStorage "); }; $scope.readWords = function(){ $scope.words = JSON.parse(sessionStorage.getItem("session_key")) || ""; // 如果读不到,则返回 null console.log("已经读取 sessionStorage "); }; $scope.clearWords = function(){ sessionStorage.removeItem("session_key"); $scope.words = ""; }; }]); //};
            </script>
        </body>
    </html>

数据的动态展示

AngularJS_简介、特性及基本使用_及其工作原理[通俗易懂]

  • <html>
        <head>
            <meta charset="UTF-8">
            <style type="text/css">
                textarea {
                    resize: none;
                }
            </style>
        </head>
        <body ng-app="myApp">
            <div ng-controller="MyCtrl" >
                <h2>Hero  </h2>
                
                <div>
                    <input type="text" ng-model="heroName"/>
                    <button ng-click="addHero()">添加</button>
                </div>
                
                <div ng-repeat="each in heros">
                    <input type="checkbox" ng-model="each.isChecked" /><span ng-bind="each.name"></span>
                </div>
                
                <button ng-click="removeHreo()">删除所选对象</button>
            </div>
            
            <script type="text/javascript" src="https://cdn.bootcss.com/angular.js/1.5.10/angular.js"></script>
            <script type="text/javascript">
                // window.onDOMContentLoaded = function(){    // 会报错 ---- 看上面的工作原理
                    angular.module("myApp", []).controller("MyCtrl", ["$scope", function($scope){ $scope.heros = [ {"name": "Groot", "isChecked": false}, {"name": "玩锤子的", "isChecked": false}, {"name": "浩克", "isChecked": false}, {"name": "洛基", "isChecked": false} ]; $scope.addHero = function(){ var isExit = false; $scope.heros.forEach(function(each, index){ if(each.name === $scope.heroName){ isExit = true; $scope.heroName = ""; }; }); if($scope.heroName && !isExit){ $scope.heros.unshift({"name": $scope.heroName, "isChecked": false}); $scope.heroName = ""; }; }; /**** // 方式1 ---- 删除 数组中不符合条件的元素 $scope.removeHreo = function(){ $scope.heros.forEach(function(each, index){ if(each.isChecked){ $scope.heros.splice(index, 1); // 从 index 开始删,删 1 个 $scope.removeHreo(); }; }); }; ****/ // 方式2 ---- 保留 数组中符合条件的元素 $scope.removeHreo = function(){ var tempArr = $scope.heros; $scope.heros = []; tempArr.forEach(function(each, index){ if(!each.isChecked){ $scope.heros.push(each); }; }); }; }]); // };
            </script>
        </body>
    </html>

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/155061.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Markdown中Latex 数学公式基本语法

    Markdown中Latex 数学公式基本语法Markdown中Latex数学公式基本语法公式排版分为两种排版:-行内公式:用\或者$包裹公式-独立公式:用\$包裹公式。例如:$\sum_{i=0}^{n}i^2$表示∑ni=0i2\sum_{i=0}^{n}i^2$$\sum_{i=0}^{n}i^2$$表示∑i=0ni2\sum_{i=0}^{n}i^2一下

  • Linux系统如何解压rar文件

    Linux系统如何解压rar文件1、下载linux版本的rar软件访问官方地址下载最新版本的linux版本rar软件2、解压下载好的安装文件tar-xzpvfrarlinux-x64-610b2.tar.gz3、编译安装进入解压后的rar文件夹,执行make命令cdrarmake4、使用rar命令解压压缩文件rarxdist.rar或者使用unrar命令unraredist.rar5、压缩文件命令raraetc.ra…

  • es6模板字符串的好处有哪些_使用es6方式实现伪数组转数组

    es6模板字符串的好处有哪些_使用es6方式实现伪数组转数组vue项目中碰到需要在模板字符串中动态渲染数组中的每一项,发现v-for不能正常渲染,于是使用原生的js语法来完成。

  • Initramfs_正在生成initramfs

    Initramfs_正在生成initramfs一、initramfs是什么  在2.6版本的linux内核中,都包含一个压缩过的cpio格式的打包文件。当内核启动时,会从这个打包文件中导出文件到内核的rootfs文件系统,然后内核检查rootfs中是否包含有init文件,如果有则执行它,作为PID为1的第一个进程。这个init进程负责启动系统后续的工作,包括定位、挂载“真正的”根文件系统设备(如果有的话)。如果内核没有在rootfs中

  • 浅谈SQL游标

    浅谈SQL游标
    游标(Cursor)是处理数据的一种方法,为了查看或者处理结果集中的数据,游标提供了在结果集中一次以行或者多行前进或向后浏览数据的能力。我们可以把游标当作一个指针,它可以指定结果中的任何位置,然后允许用户对指定位置的数据进行处理。游标允许你选择一组数据,通过翻阅这组数据记录——通常被称为数据集,检查每一个游标所在的特定的行。你可以将游标和局部变量组合在一起对每一个记录进行检查,当游标移动到下一个记录时,来执行一些外部操作。游标的另一个常见的用法是:保存查询结果以备以后使用。一个游标结果集是通过执

  • 图神经网络(GNN)的简介「建议收藏」

    近年来,图神经网络(GNN)在社交网络、知识图、推荐系统甚至生命科学等各个领域得到了越来越广泛的应用。GNN在对图节点之间依赖关系进行建模的强大功能,使得与图分析相关的研究领域取得了突破。本文介绍了图神经网络的基本原理,以及两种高级的算法,DeepWalk和GraphSage。图(Graph)在讨论GNN之前,我们先来了解一下什么是图。在计算机科学中,图是由顶点和边两部分组成的一种数据结构…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号