1.引导程序
使用ng-app开始引导一个程序:标记了AngularJS应用的作用域
- <!doctype html>
- <html lang="en" ng-app>
双括号绑定表达式:
- <p>Nothing here {{'yet' + '!'}}</p>
2.视图和模板
其核心为MVC模式
原理:在AngularJS中,一个视图是模型通过HTML模板渲染之后的映射
HTML模板:
包含ng-controller指令,和ng-repeat指令
- <html ng-app>
- <head>
- ...
- <script src="lib/angular/angular.js"></script>
- <script src="js/controllers.js"></script>
- </head>
- <body ng-controller="PhoneListCtrl">
- <ul>
- <li ng-repeat="phone in phones">
- {{phone.name}}
- <p>{{phone.snippet}}</p>
- </li>
- </ul>
- </body>
- </html>
ng-repeat的语法:对象变量 in 对象数组
模型和控制器:
$scope是作用域,为根作用域的一个后继,这里使用的是按照名称的DI。
phones即模型。
- function PhoneListCtrl($scope) {
- $scope.phones = [
- {"name": "Nexus S",
- "snippet": "Fast just got faster with Nexus S."},
- {"name": "Motorola XOOM? with Wi-Fi",
- "snippet": "The Next, Next Generation tablet."},
- {"name": "MOTOROLA XOOM?",
- "snippet": "The Next, Next Generation tablet."}
- ];
- }
AngularJS的作用域理论非常重要:
- 一个作用域可以视作模板、模型和控制器协同工作的粘接器。
- AngularJS使用作用域,同时还有模板中的信息,数据模型和控制器。
- 这些可以帮助模型和视图分离,但是他们两者确实是同步的!(绑定)任何对于模型的更改都会即时反映在视图上;任何在视图上的更改都会被立刻体现在模型中。
3.过滤器
页面上的条件过滤:
Search: <input ng-model="query">
- <ul class="phones">
- <li ng-repeat="phone in phones | filter:query">
- {{phone.name}}
- <p>{{phone.snippet}}</p>
- </li>
- </ul>
解释:
- 在这段代码中,用户在输入框中输入的数据名字称作query,会立刻作为列表迭代器(phone in phones | filter:query`)其过滤器的输入。当数据模型引起迭代器输入变化的时候,迭代器可以高效得更新DOM将数据模型最新的状态反映出来。
- 使用filter过滤器:filter函数使用query的值来创建一个只包含匹配query记录的新数组。
ngRepeat会根据filter过滤器生成的手机记录数据数组来自动更新视图。
整个过程对于开发者来说都是透明的。
4.双向绑定
使用orderProp来作为一个模型绑定,其值被应用到过滤器之后用作排序
orderBy:orderProp:按照orderProp选择的属性来排序。
- <select ng-model="orderProp">
- <option value="name">Alphabetical</option>
- <option value="age">Newest</option>
- </select>
- <ul class="phones">
- <li ng-repeat="phone in phones | filter:query | orderBy:orderProp">
- {{phone.name}}
- <p>{{phone.snippet}}</p>
- </li>
- </ul>
初始化:
$scope.orderProp = 'age';
5. XHR和依赖注入
DI:$开头的,一系列的对象。如:$scope, $http。
- function PhoneListCtrl($scope, $http) {
- $http.get('phones/phones.json').success(function(data) {
- $scope.phones = data;
- });
- $scope.orderProp = 'age';
- }
避免压缩的DI:
- PhoneListCtrl.$inject = ['$scope', '$http'];
另外一种方法:
- var PhoneListCtrl = ['$scope', '$http', function($scope, $http) { /* constructor body */ }];
6.链接
<img ng-src="{{phone.imageUrl}}">
7.路由和多视图
AngularJS中应用的路由通过$routeProvider来声明,它是$route服务的提供者。
注入器:唯一的职责是载入指定的服务模块。
当应用引导时,AngularJS会创建一个注入器,我们应用后面所有依赖注入的服务都会需要它。这个注入器自己并不知道$http和$route是干什么的,实际上除非它在模块定义的时候被配置过,否则它根本都不知道这些服务的存在。注入器唯一的职责是载入指定的服务模块,在这些模块中注册所有定义的服务提供者,并且当需要时给一个指定的函数注入依赖(服务)。这些依赖通过它们的提供者"懒惰式"(需要时才加载)实例化。
提供者是提供(创建)服务实例并且对外提供API接口的对象,它可以被用来控制一个服务的创建和运行时行为。对于$route服务来说,$routeProvider对外提供了API接口,通过API接口允许你为你的应用定义路由规则。
AngularJS模块解决了从应用中删除全局状态和提供方法来配置注入器这两个问题。和AMD或者require.js这两个模块(非AngularJS的两个库)不同的是,AngularJS模块并没有试图去解决脚本加载顺序以及懒惰式脚本加载这样的问题。这些目标和AngularJS要解决的问题毫无关联,所以这些模块完全可以共存来实现各自的目标。
模块:
- angular.module('phonecat', []).
- config(['$routeProvider', function($routeProvider) {
- $routeProvider.
- when('/phones', {templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl}).
- when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
- otherwise({redirectTo: '/phones'});
- }]);
使用$routeParams来获取URL参数:
/phone/:phoneId
- function PhoneDetailCtrl($scope, $routeParams) {
- $scope.phoneId = $routeParams.phoneId;
- }
使用nv-view来作为母版页:
<div ng-view></div>
8.事件处理器
- $scope.setImage = function(imageUrl) {
- $scope.mainImageUrl = imageUrl;
- }
使用ng-click来绑定函数(事件处理):
- <ul class="phone-thumbs">
- <li ng-repeat="img in phone.images">
- <img ng-src="{{img}}" ng-click="setImage(img)">
- </li>
- </ul>