AngularJS
相关概念
- 模板(Template)
带有Angular扩展标记的HTML - 指令(Directive)
用于通过自定义属性和元素扩展HTML的行为 - 模型(Model)
用于显示给用户并且与用户互动的数据 - 作用域(Scope)
用来存储模型(Model)的语境(context)。模型放在这个语境中才能被控制器、指令和表达式等访问到 - 表达式(Expression)
模板中可以通过它来访问作用域中的变量和函数 - 编译器(Compiler)
用来编译模板,并且对其中包含的指令和表达式进行实例化 - 过滤器(Filter)
负责格式化表达式的值,以便呈现给用户 - 视图(View)
用户看到的内容(即DOM) - 数据绑定(Data Binding)
自动同步模型中的数据和视图表现 - 控制器(Controller)
视图背后的业务逻辑 - 依赖注入(Dependency Injection)
负责创建和自动装载对象或函数 - 注入器(Injector)
用来实现依赖注入的容器(类似springBoot的factory) - 模块(Module)
用来配置注入器 - 服务(Service)
独立于视图的、可复用的业务逻辑
实例
index.html
<!DOCTYPE html>
<html ng-app>
<head>
<script src="http://code.angularjs.org/1.2.25/angular.min.js"></script>
</head>
<body>
<div ng-init="qty=1;cost=2">
<b>订单:</b>
<div>
数量: <input type="number" ng-model="qty" required>
</div>
<div>
单价: <input type="number" ng-model="cost" required>
</div>
<div>
<b>总价:</b>
</div>
</div>
</body>
</html>
- 这样的文件叫做模板, 通过编译器解析并处理模板中的这些新标记,这些经过加载、转换、渲染而成的DOM就叫做“视图”
- 第一类新标记叫做“指令(directive)”。 它们通过HTML中的属性或元素来为页面添加特定的行为。
- 上面的例子中,我们使用了 ng-app 属性,与此相关的指令(directive)则负责自动初始化我们的应用程序。
- Angular还为input 元素定义了一个指令,它负责添加额外的行为到这个元素上。例如,当它发现了input元素的required属性,它就会自动进行验证,确保所输入的文本不会是空白。
- ng-model指令则负责从变量(比如这里的qty、cost等)加载input元素的value值,并且把input元素的value值写回变量中。并且,还会根据对input元素进行校验的结果自动添加相应的css类。 比如在上面这个例子中,我们就通过这些css类把空白input元素的边框设置为红色,来表示无效的输入。
—通过自定义指令访问DOM: 对于Angular,一个程序中唯一允许接触DOM的地方就是“指令”。之所以这样要求,是因为需要访问DOM的代码难以进行自动化测试。 如果你需要直接访问DOM,那么你就应该为此写一个自定义指令—
-
第二类新标记是双大括号{{ expression | filter }},其中expression是“表达式”语句,filter是“过滤器”语句。 当编译器遇到这种标记时,它会把这些标记替换为这个表达式的计算结果。 模板中的"表达式"是一种类似于JavaScript的代码片段,它允许你读写变量。注意,表达式中所用的变量并不是全局变量。 就像JavaScript函数定义中的变量都属于某个作用域一样,Angular也为这些能从表达式中访问的变量提供了一个“作用域(scope)”。 这些存储于Angular作用域(Scope)中的变量叫做Scope变量,这些变量所代表的数据叫做“模型(model)”。 在上面的例子中,这些标记告诉Angular:“从这两个input元素中获取数据,并把它们乘在一起。”
-
这个例子中最重要的一点是:Angular提供了动态(live)的绑定: 当input元素的值变化的时候,表达式的值也会自动重新计算,并且DOM所呈现的内容也会随着这些值的变化而自动更新。 这种模型(model)与视图(view)的联动就叫做“双向数据绑定”。
invoice.html
<!DOCTYPE html>
<html ng-app="invoice1">
<head>
<script src="http://code.angularjs.org/1.2.25/angular.min.js"></script>
<script src="invoice1.js"></script>
</head>
<body>
<div ng-controller="InvoiceController as invoice">
<b>订单:</b>
<div>
数量: <input type="number" ng-model="invoice.qty" required>
</div>
<div>
单价: <input type="number" ng-model="invoice.cost" required>
<select ng-model="invoice.inCurr">
<option ng-repeat="c in invoice.currencies">{{c}}</option>
</select>
</div>
<div>
<b>总价:</b>
<span
ng-repeat="c in invoice.currencies">{{c}}
{{invoice.total(c)}} </span>
<button class="btn" ng-click="invoice.pay()">支付</button>
</div>
</div>
</body>
</html>
invocie1.js
angular.module('invoice1', []).controller('InvoiceController', function () {
this.qty = 1;
this.cost = 2;
this.inCurr = 'EUR';
this.currencies = ['USD', 'EUR', 'CNY'];
this.usdToForeignRates = {
USD: 1,
EUR: 0.74,
CNY: 6.09
};
this.total = function total(outCurr) {
return this.convertCurrency(this.qty * this.cost, this.inCurr, outCurr);
};
this.convertCurrency = function convertCurrency(amount, inCurr, outCurr) {
return amount * this.usdToForeignRates[outCurr] * 1 / this.usdToForeignRates[inCurr];
};
this.pay = function pay() {
window.alert("谢谢!");
}
})
- 这个文件中定义了一个构造函数,它用来在将来真正需要的时候创建这个控制器函数的实例。 控制器的用途是导出一些变量和函数,供模板中的表达式(expression)和指令(directive)使用。
- 在创建一个控制器的同时,我们还往HTML中添加了一个ng-controller指令。 这个指令告诉Angular,我们创建的这个InvoiceController控制器将会负责管理这个带有ng-controller指令的div节点,及其各级子节点。
- InvoiceController as invoice这个语法告诉Angular:创建这个InvoiceController的实例,并且把这个实例赋值给当前作用域(Scope)中的invoice变量。
- 在DOM中使用{{ invoice.total(…) }}表达式来绑定总价的计算结果。
同样,这个绑定也是动态(live)的,也就是说:当invoice.total函数的返回值变化的时候,DOM也会跟着自动更新。 - 表单中的“支付”按钮附加上了指令ngClick。 这意味着当它被点击时,会自动执行invoice.pay()这个表达式,即:调用当前作用域中的pay函数。