AngularJS扩展了HTML?
看了几天AngularJS的各种中文教程,一直没有理解AngularJS是做什么的。
直到今天了英文文档,才有了初步了解。
HTML是静态语言。
JavaScript是为了操作HTML 的DOM。
JQuery是对JavaScript进行封装了的类库。
那么AngularJS是什么呢?
AngularJS是把HTML进行扩展,这句话很多教程里都会提及,但是我一直不明白这个“扩展”是什么意思。
英文文档中有一句:Attaching new behavior to DOM elements, such as DOM event handling.我才知道,所谓的“扩展”就是让HTML从“静态”变成“动态”,给DOM中的元素添加一些行为,在我们看来,仿佛HTML DOM元素自己有了自己的行为,不需要通过JavaScript去操纵,需要用到JavaScript的地方就是用JavaScript去描述DOM元素的行为。
AngularJS适用场景?
AngularJS适用于CRUD操作的web应用,不适用与游戏、图形编辑器这种DOM操作频繁的web应用。
AngularJS的一些概念
网上的太杂乱,还说不清,自己看了看,感觉理解深入了一些。
Template 模版: 含有附加标记的HTML;
Directives 指令: 扩展HTML所用的自定义属性和元素
Model 模型: 用户看到的并与之交互的视图View中的数据
Scope 范围: 存储模型Model的一个context,以便控制器、指令、表达式能够访问模型Model。
Expressions 表达式: 访问Scope中的variables和functions
Compiler 编译器: 解析模版template,实例化指令directives和表达式expressions
Filter 过滤器: 把一个表达式expression的值按照一定的格式展示给用户;
View 视图: 用户看到的。(也可以叫HTML DOM)
Data Binding 数据绑定: 同步模型Model和视图View中的数据。
Controller 控制器: 视图View背后的业务逻辑。
Dependency Injection 依赖注入:(创建creates+连接wires)(对象objects+功能functions)
Injector 注入器: 依赖注入的容器。
Module 模块: 一个用来配置注入器的容器,里边包含了一个app的控制器、服务、过滤器、指令
Service 服务: 独立于视图Views的可复用的业务逻辑。
AngularJS例子
<div ng-app ng-init="qty=1;cost=2"> <b>Invoice:</b> <div> Quantity: <input type="number" min="0" ng-model="qty"> </div> <div> Costs: <input type="number" min="0" ng-model="cost"> </div> <div> <b>Total:</b> {{qty * cost | currency}} </div> </div>
上边的这段代码,和HTML很像,就是多了一些新的标记,在Angular中,这个文件就叫模版“template”。
当Angular启动web app时,就用编译器“compiler”解析并处理代码中的那些标记。
解析后的DOM就是用户看到的视图“view”。
第一种新的标记就叫指令“directives”。他们给HTML中的属性或元素添加了特定的行为。在这个例子中,我们用ng-app这个属性,关联到了一个自动初始化application的指令。Angular还为input元素定义了一个指令,给这个元素添加了某些行为。ng-model指令stores/updates输入框中的值into/from一个变量。
范围Scope是隐藏的;
视图View是可见的DOM;
上图中的蓝色箭头形象的展示了“双向绑定”的含义。
定制访问DOM的指令:在Angular中,一个应用访问DOM的唯一位置就是在指令内部,否则会导致DOM难以测试。如果你要直接访问DOM,最好写一个定制的指令。
第二种新的标记就是双大括号{{expression|filter}},当编译器遇到这个标记,就会用对应的值进行替换。expression就和JavaScript中可读写的变量一样,这些变量就是在scope中的那些数据,也可以是模型model对应的值。
首先实例化一个InvoiceController的对象invoice,存储在Scope中,这个invoice的属性和行为在Controller中进行了定义;
视图中的两个ng-model指令把DOM元素的值和invoice对象的属性进行捆绑;
控制器的total和pay行为和DOM中的指令也进行绑定。
======================================================================
依赖注入来了~
Service:当一个应用越来越大,可以将一些控制器中的公共行为放到一个Service中。
HTML代码:
<div ng-app="invoice2" ng-controller="InvoiceController as invoice"> <b>Invoice:</b> <div> Quantity: <input type="number" min="0" ng-model="invoice.qty" required > </div> <div> Costs: <input type="number" min="0" ng-model="invoice.cost" required > <select ng-model="invoice.inCurr"> <option ng-repeat="c in invoice.currencies">{{c}}</option> </select> </div> <div> <b>Total:</b> <span ng-repeat="c in invoice.currencies"> {{invoice.total(c) | currency:c}} </span> <button class="btn" ng-click="invoice.pay()">Pay</button> </div> </div>
控制器代码:
angular.module('invoice2', ['finance2']) .controller('InvoiceController', ['currencyConverter', function(currencyConverter) { this.qty = 1; this.cost = 2; this.inCurr = 'EUR'; this.currencies = currencyConverter.currencies; this.total = function total(outCurr) { return currencyConverter.convert(this.qty * this.cost, this.inCurr, outCurr); }; this.pay = function pay() { window.alert("Thanks!"); }; }]);
Service代码:
angular.module('finance2', []) .factory('currencyConverter', function() { var currencies = ['USD', 'EUR', 'CNY']; var usdToForeignRates = { USD: 1, EUR: 0.74, CNY: 6.09 }; var convert = function (amount, inCurr, outCurr) { return amount * usdToForeignRates[outCurr] / usdToForeignRates[inCurr]; }; return { currencies: currencies, convert: convert }; });
依赖注入(DI)是一种软件设计模式,主要用于处理怎么样创建对象或功能函数以及怎样处理依赖关系。
Angular中的每一个概念(指令、过滤器、控制器、服务。。。)都是使用DI思想。在Angular中,DI容器叫做注入器。
为了使用DI,需要有这样一个空间,所有应该一起工作的东西都注册其中。在AngularJS中,这个空间叫做模块module。当一个AngularJS应用启动,ng-app指令就定义了一个模块。
在上边的例子中,模版通过指令ng-app="invoice2"告诉应用,这个模块是应用的主模块。
代码angular.module('invoice2',['finance2'])指定invoice2模块依赖finance2模块。通过这个,Angular使用InvoiceController控制器的时候,也可以使用currencyConverter服务。