AngularJS 是一个建立富客户端应用的JavaScript MVC框架。你仍然须要具备服务端后台,但大多数的用户交互逻辑将放到客户端上处理。它能够建立单页的应用程序,一个页面的应用仅仅须要HTML,CSS和JavaScript在客户端。它的目标是加强页面的模型-视图-控制(MVC)的功能,为简化开发和测试。单页Web应用(single page web application,SPA),就是只有一张Web页面的应用。浏览器一开始会加载必需的HTML、CSS和JavaScript,全部的操做都在这张页面上完成,由JavaScript来控制不一样view在这个页面上的呈现。本文源于Youtube上一个不错的AngularJs的入门教程视频:AngularJS Fundamentals In 60-ish Minutes,主要讲解了AngularJs中Directive,Data Binding,Filter和Module的概念和用法。我的认为这四个概念是AngularJs的核心,支撑起了AngularJs的骨架。掌握了他们对全局上把握AngularJs颇有帮助。进阶则须要大量实践和官网API文档的阅读。html
看看下图大体就能够了解AngularJs有何能耐。angularjs
首先从官网下载angular.min.js和angular-route.min.js。 能够从官网下载(https://angularjs.org/或https://code.angularjs.org/)web
在VS中建立一个空的Empty Web项目。json
Directive 和 Data Bindingbootstrap
AngularJs 中的Directive概念不是很容易理解,入门阶段可暂且将其理解为用来扩展HTML的一种tag. Angularjs会解析这些tag,以实现Angularjs的Magic.api
能够对照传统的Imperative UI来理解AngularJs的Declarative UI:数组
AngularJs以前咱们实现前台页面逻辑通常是经过给HTML元素设置ID,而后使用Javascript或jQuery来操纵HTML DOM,这就是典型的Imperative UI。 而AngularJs再也不须要给HTML元素设置ID,而使用Declarative,由Declarative“指导”HTML 元素的行为。我的认为这样的好处之一就是开发人员看到一个HTML 元素及其Directive大概就能够理解其运行时的行为。而在传统的Imperative UI中,HTML 元素的ID信息并不能给你带来任何有用的信息。浏览器
下面代码使用了两个Directive:ng-app 和 ng-model.app
ng-app: 用于auto-bootstrap 一个AngularJs应用。这是必须的一个Directive,通常加在HTML的根对象上(以下代码所示)。更详细解释,移步官网:https://docs.angularjs.org/api/ng/directive/ngApp框架
ngModel: 用于在property和HTML控件(input,select, textarea)之间创建双向的Data Binding,也就是说HTML控件的值改变会反应到property上,反过来也一样成立。property就是经过{{}}建立的一个对象。
下面代码展现了将文本控件和name之间创建了Data Binding.
<!DOCTYPE html> <html ng-app> <head> <title>Using Directives and Data Binding Syntax</title> </head> <body> <div class="container"> Name: <input type="text" ng-model="name" /> {{name}} </div> <script src="angular.min.js"></script> </body> </html>
Directive能够用“x-”或者“data-”做为前缀。Directive能够放置于元素名、属性、class、注释中。
<!DOCTYPE html> <html data-ng-app=""> <head> <title>Using Directives and Data Binding Syntax</title> </head> <body> <div class="container"> Name: <input type="text" data-ng-model="name" /> {{name}} </div> <script src="angular.min.js"></script> </body> </html>
下面是HTML运行之后的结果。
下面例子展现了经过ng-init和ng-repeat来遍历操做一个数组的用法。
<!DOCTYPE html> <html data-ng-app=""> <head> <title>Iterating with the ng-repeat Directive</title> </head> <body> <div class="container" data-ng-init="names = ['Terry','William','Robert','Henry']"> <h3>Looping with the ng-repeat Directive</h3> <ul> <li data-ng-repeat="name in names">{{name}}</li> </ul> </div> <script src="angular.min.js"></script> </body> </html>
更多directve的用法,参考官网https://docs.angularjs.org/api
Filter
做用就是接收一个输入,经过某个规则进行处理,而后返回处理后的结果。主要用于对数组过滤,对数组中的元素进行排序, 对数据作格式化处理等。
AngualrJS内置了一些过滤器,它们是:currency(货币)、date(日期)、filter(子串匹配)、json(格式化json对象)、limitTo(限制个数)、lowercase(小写)、uppercase(大写)、number(数字)、orderBy(排序)。总共九种。除此以外还能够自定义过滤器,这个就强大了,能够知足任何要求的数据处理。
下面代码展现了数据过滤,排序和大小写转换的实现。每一个Filter跟在数据后,并有|隔开。
<!DOCTYPE html> <html data-ng-app=""> <head> <title>Using Filter</title> </head> <body> <div class="container" data-ng-init="customers = [{name:'Terry Wu',city:'Phoenix'}, {name:'Terry Song',city:'NewYork'},{name:'Terry Dow',city:'NewYork'}, {name:'Henry Dow',city:'NewYork'}]"> Names: <br /> <input type="text" data-ng-model="name" /> <br /> <ul> <li data-ng-repeat="cust in customers | filter:name | orderBy:'city'">{{cust.name | uppercase}} - {{cust.city | lowercase}}</li> </ul> </div> <script src="angular.min.js"></script> </body> </html>
运行的结果:
Module
Module就是一个容器,用于管理一个AngularJS应用的各个部分,是AngularJS中很重要的概念。一个独立的AngularJS功能模块能够封装成一个Module,其做用和C#应用程序中Assembly做用相似。C#中咱们经过main函数来bootstrap应用程序。而AngularJS则经过na-app="moduleName"的方式来bootstrap一个AngularJS功能模块。moduleName就是Module对象的name.
下图是一个Module有哪些常见部分组成。
Config/Route:用于配置AngularJS应用的路由(AngularJS),做用相似于ASP.NET MVC应用中的Config/Route。
Filter:对数据起过滤做用,上文有解释。
Directive: 扩展HTML,AngularJS中最重要的概念。没有Directive就没有AngularJS。
Controller: 做用相似于ASP.NET MVC应用中的Controller。做用有两个:实现页面上的业务逻辑,以及对$scope(model)进行操做。 AngularJS则经过内建的Data-Binding机制将model绑定到view(HTML控件)。使用了angularJS后,通常不会经过代码对HTML DOM元素进行操做 (这正是angularJS的神奇之处)。
Factory/Service/Provider/Value: 提供方法供Controller使用。 大多数时候经过他们实现对数据源的访问,以及实现一些通用的逻辑以在不一样的Controller中共享。好比Restful API就是常见的数据源。
下面这段代码实现了上面实例的相同的功能,差别就在于这个实例经过建立一个module(angularJS应用),并在module下添加contorller来实现上面的功能。在SimpleController(Controller)中,咱们建立了customers(Model)并进行数据初始化, View(Html控件)则直接绑定到customers(Model)。$Scope是一个AngualrJs moduel中全部model的容器对象。Controller须要经过$Scope来访问model。View则经过$Scope来访问Controller和model。
这个例子比上面例子更接近实际工程中的用法。
<!DOCTYPE html> <html data-ng-app="demoApp"> <head> <title>Using module Controller</title> </head> <body> <div data-ng-controller="SimpleController"> Names: <br /> <input type="text" data-ng-model="name" /> <br /> <ul> <li data-ng-repeat="cust in customers | filter:name | orderBy:'city'">{{cust.name | uppercase}} - {{cust.city | lowercase}}</li> </ul> </div> <script src="angular.min.js"></script> <script> var demoApp = angular.module("demoApp", []); demoApp.controller("SimpleController", function ($scope) { $scope.customers = [ { name: 'Terry Wu', city: 'Phoenix' }, { name: 'Terry Song', city: 'NewYork' }, { name: 'Terry Dow', city: 'NewYork' }, { name: 'Henry Dow', city: 'NewYork' } ]; }); </script> </body> </html>
<!DOCTYPE html> <html data-ng-app="demoApp"> <head> <title>Using Controller</title> </head> <body> <div data-ng-controller="SimpleController"> Names: <br /> <input type="text" data-ng-model="name" /> <br /> <ul> <li data-ng-repeat="cust in customers | filter:name | orderBy:'city'">{{cust.name | uppercase}} - {{cust.city | lowercase}}</li> </ul> </div> <script src="angular.min.js"></script> <script> var demoApp = angular.module("demoApp", []); var controllers = {}; controllers.SimpleController = function ($scope) { $scope.customers = [ { name: 'Terry Wu', city: 'Phoenix' }, { name: 'Terry Song', city: 'NewYork' }, { name: 'Terry Dow', city: 'NewYork' }, { name: 'Henry Dow', city: 'NewYork' } ]; } demoApp.controller(controllers); </script> </body> </html>
<!DOCTYPE html> <html data-ng-app="demoApp"> <head> <title>Using Controller</title> </head> <body> <div> <div data-ng-view=""></div> </div> <script src="angular.min.js"></script> <script src="angular-route.min.js"></script> <script> var demoApp = angular.module('demoApp', ['ngRoute']); demoApp.config(function ($routeProvider) { $routeProvider .when('/', { controller: 'SimpleController', templateUrl: 'Partials/View1.html' }) .when('/view2', { controller: 'SimpleController', templateUrl: 'Partials/View2.html' }) .otherwise({redirectTo:'/'}); }); var controllers = {}; controllers.SimpleController = function ($scope) { $scope.customers = [ { name: 'Terry Wu', city: 'Phoenix' }, { name: 'Terry Song', city: 'NewYork' }, { name: 'Terry Dow', city: 'NewYork' }, { name: 'Henry Dow', city: 'NewYork' } ]; $scope.addCustomer = function () { $scope.customers.push({ name: $scope.newCustomer.name, city: $scope.newCustomer.city }); }; } demoApp.controller(controllers); </script> </body> </html>
下图展现了Module及其各个组成部分的关系。
下面实例经过config配置module的route实现一个SPA实例。首先建立View1.html 和View2.html。 目录结构以下图.
<div> <h2>View1</h2> Names: <br /> <input type="text" data-ng-model="filter.name" /> <br /> <ul> <li data-ng-repeat="cust in customers | filter:filter.name | orderBy:'city'">{{cust.name | uppercase}} - {{cust.city | lowercase}}</li> </ul> <br /> Customer Names:<br /> <input type="text" data-ng-model="newCustomer.name" /> <br /> Customer City:<br /> <input type="text" data-ng-model="newCustomer.city" /> <br /> <button data-ng-click="addCustomer()">Add Customer </button> <br /> <a href="#/view2">View 2</a> </div>
<div> <h2>View2</h2> City: <br /> <input type="text" data-ng-model="city" /> <br /> <ul> <li data-ng-repeat="cust in customers | filter:city | orderBy:'city'">{{cust.name | uppercase}} - {{cust.city | lowercase}}</li> </ul> </div>
经过$routeProvider来配置当前页面中view1 和view2 的路由,已经每一个view所对应的controller。 view1和view2会显示在当前页面标注了ng-view的位置。
同时经过config咱们解耦了controller和HTML标签。 上面的例子,咱们须要给html标签添加ng-controller tag来使用controller。这边直接经过config完成这样的配置。
<!DOCTYPE html> <html data-ng-app="demoApp"> <head> <title>View</title> </head> <body> <div> <div data-ng-view=""></div> </div> <script src="angular.min.js"></script> <script src="angular-route.min.js"></script> <script> var demoApp = angular.module('demoApp', ['ngRoute']); demoApp.config(function ($routeProvider) { $routeProvider .when('/', { controller: 'SimpleController', templateUrl: 'Partials/View1.html' }) .when('/view2', { controller: 'SimpleController', templateUrl: 'Partials/View2.html' }) .otherwise({redirectTo:'/'}); }); var controllers = {}; controllers.SimpleController = function ($scope) { $scope.customers = [ { name: 'Terry Wu', city: 'Phoenix' }, { name: 'Terry Song', city: 'NewYork' }, { name: 'Terry Dow', city: 'NewYork' }, { name: 'Henry Dow', city: 'NewYork' } ]; $scope.addCustomer = function () { $scope.customers.push({ name: $scope.newCustomer.name, city: $scope.newCustomer.city }); }; } demoApp.controller(controllers); </script> </body> </html>
效果以下图。
最后一个实例更接近实际工程中的用法,引入了Factory来初始化数据(实际工程中,在这里可访问webAPI获取数据完成初始化),Controller中则经过Factory得到数据。
<!DOCTYPE html> <html data-ng-app="demoApp"> <head> <title>Using Factory</title> </head> <body> <div> <div data-ng-view=""></div> </div> <script src="angular.min.js"></script> <script src="angular-route.min.js"></script> <script> var demoApp = angular.module('demoApp', ['ngRoute']); demoApp.config(function ($routeProvider) { $routeProvider .when('/', { controller: 'SimpleController', templateUrl: 'Partials/View1.html' }) .when('/view2', { controller: 'SimpleController', templateUrl: 'Partials/View2.html' }) .otherwise({ redirectTo: '/' }); }); demoApp.factory('simpleFactory', function () { var customers = [ { name: 'Terry Wu', city: 'Phoenix' }, { name: 'Terry Song', city: 'NewYork' }, { name: 'Terry Dow', city: 'NewYork' }, { name: 'Henry Dow', city: 'NewYork' } ]; var factory = {}; factory.getCustomers = function () { return customers; } return factory; }); var controllers = {}; controllers.SimpleController = function ($scope, simpleFactory) { $scope.customers = []; init(); function init() { $scope.customers = simpleFactory.getCustomers(); } $scope.addCustomer = function () { $scope.customers.push({ name: $scope.newCustomer.name, city: $scope.newCustomer.city }); }; } demoApp.controller(controllers); </script> </body> </html>