AngularJS前端框架
AngularJS的简单介绍:
AnjulrJS 是用于开发动态页面的框架,它专注于扩展HTML的功能,提供动态数据绑定(data binding),而且它能跟其它框架(如jQuery)合作融洽,最适于开发客户端的单页面应用。
AngularJS:
- ng-app
- ng-model=“yourName”
- {{ yourName }}
首先,我们写上了最重要(也是最容易被忘记)的部分:<html>元素的ng-app属性。少了这个属性,AngularJS就没法开始工作。
其次,我们告诉AngularJS,对页面上的“yourName” 这个Model进行双向数据绑定。
第三,我们告诉AngularJS,在“{{ yourName }}”这个指令模版上显示“yourName”这个Model的数据。
好处:
我们开发了一个动态应用,一个本来要耗费多得多的时间和代码来开发的应用:在这里,我们不需要给双向数据绑定写任何规则,不需要给更新model和view写任何代码,甚至不需要编写任何model——事实上,我们根本都还没开始碰JavaScript。我们不需要写代码,直到我们想开发更个性化的应用行为为止。
angular.module:
要定义一个AngularJS应用,我们先得定义一个AngularJS模块(angular.module)。所谓AngularJS模块,其实就是一系列函数的集合,当应用被启动时,这些函数就会被执行
var app = angular.module(myApp,[]) ;用这行代码,我们创建了叫做“myApp”的AngularJS模块。
<html ng-app="myApp">在页面上实例化一个模块,我们使用ng-app这个指令,它的存在告诉AngularJS,我们的模块拥有那一部分的DOM结构。传入我们应用的名字作为ng-app指令的值,我们就可以在index.html页面上实例化我们的应用(模块),刷新页面,现在AngularJS就会引导启动我们的myApp。
定义好了我们的应用,就可以开始创建它的其他部分了。我们会使用$scope来创建,这也是AngularJS最重要的概念之一。我们会在这个七步系列的第二部分深入学习$scope服务。
Ss
scopes:
$scope是一个把view(一个DOM元素)连结到controller上的对象。在我们的MVC结构里,这个 $scope 将成为model,它提供一个绑定到DOM元素(以及其子元素)上的excecution context。
但 $scope 实际上就是一个JavaScript对象,controller和view都可以访问它,所以我们可以利用它在两者间传递信息。在这个 $scope 对象里,我们既存储数据,又存储将要运行在view上的函数。
每一个Angular应用都会有一个 $rootScope。这个 $rootScope 是最顶级的scope,它对应着含有 ng-app 指令属性的那个DOM元素。如果页面上没有明确设定 $scope ,Angular 就会把数据和函数都绑定到这里,app.run(function($rootScope){
$rootScope.name="Ari Lerner";
});其中app.run(){}类似于main方法;
{{name}};我们可以在view的任何地方访问这个name属性,使用模版表达式{{}}
ng-controller:
要真正看到scope的强大功能,让我们给一个DOM元素加上controller,它将创建这个元素的$scope ,让我们跟这个元素互动;
<div ng-controller="MyController">
{{person.name}}
</div>
ng-controller指令给所在的DOM元素创建了一个新的$scope 对象,并将这个$scope 对象包含进外层DOM元素的$scope 对象里。在上面的例子里,这个外层DOM元素的$scope 对象,就是$rootScope 对象。
app.controller('MyContoller',function($scope){
$scope.person={
name:"Ari Lerner"
};
});
现在我们可以在有ng-controller=’MyController’属性的DOM元素的任何子元素里访问这个person 对象,因为它在$scope上。
唯一的例外:有些指令属性可以选择性地创建一个独立的scope,让这个scope不继承它的父scope们。
除了一个例外,所有scope都遵循原型继承(prototypal inheritance),这意味着它们都能访问父scope们。对任何属性和方法,如果AngularJS在当前scope上找不到,就会到父scope上去找,如果在父scope上也没找到,就会继续向上回溯,一直到$rootScope 上。
app.controller('ParentController',function($scope){
$scope.person={greeted:false};
});
app.controller('ChildController',function($scode)
$scope.sayHellow=function(){
$scope.person.geeted=true;
}
});
当我们在view里把ChildController 绑定到ParentController 之下,在子元素里我们就能访问ParentController 创建的父scope的属性,像访问ChildController 自己的scope中的属性一样:
<div ng-Controller="ParentController">
<div ng-Controller="ChildController">
<input type="text" ng-model="person.name" placeholder="name"></input>
<a ng-click="sayHello()">Say Hello</a>
</div>
{{person}}
</div>
数据绑定和AJAX
文本输入框和页面的双向绑定:
<div ng-controller="MyController">
<input type="text" ng-model="perdon.name" placeholder="Enter your name"></input>//后台显示
<h5>Hello{{person.name}}</h5>//前端显示
</div>
当改变前台的view时,后台model也随之改变,数据绑定方向:从view到model。
app.controller('MyController',function($scope){
$scope.person={name:"Ari Lerner"};
var updateClock=function(){
$scope.clock=new Date();
};
var timer=setInterval(function(){
$scope.$apply(update(clock);
},1000);
updateClock();
});
<div ng-controller="MyController">
<h5>{{clock}}</h5>
</div>
改变后台model时,前台的view也随之改变,数据绑定的方向:从model到view。
互动
前面我们把数据绑定在了文本输入框上。请注意, 数据绑定并非只限于数据,我们还可以利用绑定调用 $scope 中的函数。
对按钮、链接或任何其他的DOM元素,我们都可以用另一个指令属性来实现绑定:ng-click 。
这个 ng-click 指令将DOM元素的鼠标点击事件(即 mousedown 浏览器事件)绑定到一个方法上,当浏览器在该DOM元素上鼠标触发点击事件时,此被绑定的方法就被调用。跟上一个例子相似,这个绑定的代码如下:
<div ng-controller="DemoController">
<h4>The Simplest adding machine ever</h4>
<button ng-click="add(1)" class="button">Add</button>
<button ng-click="subtract(1)"class="button">subtract</button>
<h4>Current count:{{counter}}</h4>
</div>
不论是按钮还是链接都会被绑定到包含它们的DOM元素的controller所有的 $scope 对象上,当它们被鼠标点击,Angular就会调用相应的方法。注意当我们告诉Angular要调用什么方法时,我们将方法名写进带引号的字符串里。
app.contoller('DemoController',function($scope){
$scope.counter=0;
$scope.add=function(amount){ $scope.counter+=amount;};
});
指令和表达式:
目前为止,我们已提到过几次“指令属性”的概念,但从未深入探讨过它到底是什么。实际上,“指令属性”就是绑定在DOM元素上的函数,它可以调用方法、定义行为、绑定controller及$scope对象、操作DOM等。
当浏览器启动、开始解析HTML(像平时一样)时,DOM元素上的指令属性就会跟其他属性一样被解析。
当一个Angular.js应用启动,Angular编译器就会遍历DOM树(从有ng-app指令属性的那个DOM元素开始,如我们在本系列第一篇里所提过的),解析HTML,寻找这些指令属性函数。
当在一个DOM元素上找到一个或多个这样的指令属性函数,它们就会被收集起来、排序,然后按照优先级顺序被执行,每个指令属性都有自己的优先级。
Angular.js应用的动态性和响应能力,都要归功于指令属性。之前我们已经看过一些指令属性的用例:
ng-model
<inpput ng-model="name" name="Name" placeholder="Enter your name"/>
<h4>your name{{name}}<h4>
ng-model 指令属性是将doc文本框输入的内容和controller中的$scope model 绑定,其实现过程是在输入的值上绑定一个$watch函数(类似于javascri上的监听函数),
{{ 表达式 }}
这个双大括号指令属性,使用$watch()函数,给括号内的表达式注册了一个监听器。正是这个$watch函数,让Angular.js能够实时自动更新view。
表达式:
表达式经过Angular.js的处理,具有以下重要而独特的性质:
- 所有表达式都在scope这个context里被执行,因此可以使用所有本地 $scope 中的变量。
- 如果一个表达式的执行导致类型错误或引用错误,这些错误将不会被抛出。
- 表达式里不允许任何控制函数流程的功能(如if/else等条件语句)
- 表达式可接受一个或多个串联起来的过滤器。
表达式都运行在调用它们的scope里,所以一个表达式可访问并操作其scope上的一切。由此,你可以使用表达式遍历其scope的属性(我们在ng-repeat中会看到这一应用)、调用scope里的函数,或者对scope中的变量进行数学运算。
ng-init:
<b ng-init name='name="Ari Lerner"'>hello {{name}}</b>
主要进行初始化,在程序运行之前给相应的变量进行赋值。
ng-click:指令属性给dom元素添加了一个点击事件的监听器,当dom元素发生点击事件(button或者link时),angular.js就会执行表达式的内容,并相应的跟新view。
<button ng-click="counter=counter+1">And one</but
current counter:{{counter}}
我们也可以用ng-click来调用controller中写好并绑定在¥scope上的函数;
<button ng-click="sayhello()">Say Hello</button>
controller里的函数:
app.controller('MyController',function($scope){
$scope.sayHello=function(){
alter("hello");
}
});
ng-repeat: 用于遍历数组元素,使用$scope对象。
$scope.roommates=[
{name:'zhangsan'},
{name:'lisi'},
{name:'wangermazi'}
];
<ul>
<li ng-repeat="person in roommates">{{person.name}}</li></ul>
ng-repeat可以遍历key-value的数据集合:
$scope.people={
'A':'white',
'B':'black',
'C':'yellow'
}
要遍历它,我们可以给ng-repeat指令属性赋予这个表达式: (key, value) in object:
<ul>
<li ng-repeat="(name,color in people)"> {{name}}'s like{{color}}</li></ul>
服务:Services
从内存和效率角度出发,controllers仅当需要的时候才会被实例化并在不需要的时候被丢弃掉,这就意味着每一次我们使用route跳转或者重载视图,当前的controller会被销毁。
Services可以让我们在整个应用的生命周期中保存数据并且可以让controllers之间共享数据。
Services都是单例的,就是说在一个应用中,每一个Serice对象只会被实例化一次(用$injector服务),主要负责提供一个接口把特定函数需要的方法放在一起,在编译的时候被使用。
最常见创建服务的方法就是用angular.module API 的factory模式。
angular.module('MyApp.services',[]).factory('githubService',function(){
var serviceInstance=[];
return serviceInstance;
)