AngularJs教程-快速入门

来源:互联网 发布:2017爱情电影 知乎 编辑:程序博客网 时间:2024/05/16 11:32

AngularJs开发应用

主要介绍AngularJs的特性、应用骨架、应用剖析、与服务器的交互、及简单的Demo

关于AngularJs

AngularJS是一款来自Google的前端JS框架。简称其为 ng 。这款框架最核心特性有:MVC、模块化、自动化双向数据绑定、语义化标签、依赖注入,等等。

AngularJS框架通过TDD(测试驱动)的方式开发的,从这个角度看,AngularJS是敏捷开发的一次成功实践。

使用了指令的概念,AngularJS对DOM操作进行了彻底的封装。

AngularJS框架是完全免费开源的。

关于 ng 的几点:

  • 对 IE 方面,它兼容 IE8 及以上的版本。
  • 与 jQuery 集成工作,它的一些对象与 jQuery 相关对象表现是一致的。
  • 使用 ng 时不要冒然去改变相关 DOM 的结构

HelloWorld

第一个Demo,HelloDynamic.html

<html ng-app><head>  <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>  <script src="controllers.js"></script></head><body>  <div ng-controller='HelloController'>    <input ng-model='greeting.text'>    <p>{{greeting.text}}, World</p>  </div></body></html>

controllers.js

function HelloController($scope) {  $scope.greeting = { text: 'Hello' };}

这里写图片描述

数据绑定

我们没有在输入框中注册任何change事件监听器就可以让UI自动刷新,AngularJs会自动把输入框和花括号中的文本更新为所获得值。

依赖注入

function HelloController($scope) {  $scope.greeting = { text: 'Hello' };}

scopescope对象 放在HelloController的构造函数里面,然后就可以获取它了。

当然scope使location,只要把$location对象放在我们的构造函数中即可。

这种神奇的效果是通过Angular的依赖注入机制实现的。

指令

我们在模板中看到一些新的属性,这些属性不属于HTML规范。我们引进了花括号用来实现数据的绑定;引入了ng-controller用来指定每个控制器负责监视视图的哪个部分;引入了ng-model,用来把输入数据绑定到模型中的以部门属性上。我们把这些叫做HTML扩展命令。

<html ng-app><head>  <title>Your Shopping Cart</title></head><body ng-controller='CartController'><h1>Your Shopping Cart</h1><div ng-repeat='item in items'>  <span>{{item.title}}</span>  <input ng-model='item.quantity'>  <span>{{item.price | currency}}</span>  <span>{{item.price * item.quantity | currency}}</span>  <button ng-click="remove($index)">Remove</button></div><script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script><script>  function CartController($scope) {    $scope.items = [      {title: 'Paint pots', quantity: 8, price: 3.95},      {title: 'Polka dots', quantity: 17, price: 12.95},      {title: 'Pebbles', quantity: 5, price: 6.95}    ];    $scope.remove = function(index) {      $scope.items.splice(index, 1);    };  }</script></body></html>

这里写图片描述

<html ng-app>

ng-app 属性用来告诉Angular页面中的哪一个部分需要接受它的管理。放在html标签中,说明它管理整个页面。

<body ng-controller='CartController'>

使用一个叫做控制器的JavaScript类来管理页面中的区域。在body标签中引入一个控制器,就是在声明CartController将会管理介于和之间的所有内容。

<div ng-repeat='item in items'>

ng-repeat的意思是,对于items数据中的每一个元素,都把

中的DOM结构复制一份(包含div本身)。对于div的每一分拷贝,都会把一个叫做item的属性设置给它,这样我们就可以在模板中使用这份拷贝的元素了。如你所见,这样一来就会产生3份

<span>{{item.title}}</span>

{{item.title}}将会获取循环中当前item,然后把这个item的title属性值插入到DOM中。

<input ng-model='item.quantity'>

定义ng-model将会在输入框和item.quantity的值之间创建数据的绑定关系。

<span>{{item.price | currency}}</span>

单价或者总价都有美元的格式显示。Angular带有一种2叫做过滤器(filter)的特性,我们可以用它来转换文本的格式,有一个内置过滤器叫做currency(货币),来显示美元格式化。

<button ng-click="remove($index)">Remove</button>

这个按钮可以让用户删除购物车中的项目,$index代表过程中的循环计数,这样就可以知道要删除哪条记录了。

<html ng-app='myApp'><body ng-controller='TextController'><p>{{someText.message}}</p><script    src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script><script>  var myAppModule = angular.module('myApp', []);  myAppModule.controller('TextController',      function($scope) {        var someText = {};        someText.message = 'You have started your journey.';        $scope.someText = someText;      });</script></body></html>

我们把ng-app设置成模块名称myApp,然后调用Angular对象创建一个名为myApp的模块,并且把控制器函数传递给myApp模块的controller函数。

流程

  1. 用户请求应用起始页
  2. 用户的浏览器向服务器发起一次HTTP连接,然后加载index.html页面,这个页面里面包含模板。
  3. Angular被加载到页面中,等待页面加载完成,然后查找ng-app指令,用来定义模板边界。
  4. Angular遍历模板,查找指令和绑定关系,这将启动一些列的动作:注册监听器、执行一些DOM操作、从服务器获取初始化数据。这项工作的结果是,应用将会启动起来,并且模板被转换成DOM视图。
  5. 连接到服务器去加载需要展示给用户的其他数据。

ng-change

数据变化触发事件
这里写图片描述

<!doctype html><html ng-app>  <head>    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>  </head>  <body>    <form ng-controller="StartUpController">      Starting: <input ng-change="computeNeeded()"                       ng-model="funding.startingEstimate">      Recommendation: {{funding.needed}}    </form>    <script>      function StartUpController($scope) {        $scope.funding = { startingEstimate: 0 };        $scope.computeNeeded = function() {          $scope.funding.needed = $scope.funding.startingEstimate * 10;        };      }    </script>  </body></html>

$watch

不管他是通过何种途径进行刷新的,我们需要使用scopewatch函数。

<!doctype html><html ng-app>  <head>    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>  </head>  <body>    <form ng-controller="StartUpController">      Starting: <input ng-model="funding.startingEstimate">      Recommendation: {{funding.needed}}    </form>    <script>      function StartUpController($scope) {        $scope.funding = { startingEstimate: 0 };        computeNeeded = function() {          $scope.funding.needed = $scope.funding.startingEstimate * 10;        };        $scope.$watch('funding.startingEstimate', computeNeeded);      }    </script>  </body></html>

监控多个东西

$scope.$watch('things.a+things.b',callMe(...));

当然a和b也可以属于不同的对象,只要需要,这个列表可以无限长。

需要监控things对象上的所有属性,可以这样做:

$scope.$watch('things',callMe(...),true);

true属性是请求Angular遍历things的属性,当其中任何一个属性发生变化时就会触发callMe事件。

使用Moudle模块组织依赖关系

<!doctype html><html lang='en' ng-app='ShoppingModule'>  <head>    <title>Shopping Cart</title>    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>    <link href="bootstrap.css" rel="stylesheet">  </head>  <body ng-controller="ShoppingController">    <h1>Shop!</h1>    <table>      <tr ng-repeat="item in items">        <td>{{item.title}}</td>        <td>{{item.description}}</td>        <td>{{item.price | currency}}</td>      </tr>    </table>    <script>      function ShoppingController($scope, Items) {        $scope.items = Items.query();      }      var shoppingModule = angular.module('ShoppingModule', []);      // Set up the service factory to create our Items interface to the      // server-side database      shoppingModule.factory('Items', function() {        var items = {};        items.query = function() {          // In real apps, we'd pull this data from the server...          return [            {title: 'Paint pots', description: 'Pots full of paint', price: 3.95},            {title: 'Polka dots', description: 'Dots with polka', price: 2.95},            {title: 'Pebbles', description: 'Just little rocks', price: 6.95}          ];        };        return items;      });    </script>  </body></html>

这里写图片描述

利用模块和模块内置的依赖注入功能,我们可以把控制器写的更加的简单:

function ShoppingController($scope, Items) {//俩个参数是无序的        $scope.items = Items.query();}

Items已定义为一个服务,定义的方式有三种:
1. provider(name,Object OR constructor()),一个可配置的服务,创建的逻辑比较复杂。如果你传递了一个Object做为参数,那么这个Object必须带有一个名为getAngular2.factory(name,getFunction()),一个不可配置的服务,创建逻辑比较复杂。你需要指定一个函数,当调用这个函数的时候,会返回服务的实例。你可以把它看成provider(name,{$getFunction()})的形式。
3. service(name,constructor()),一个不可配置的服务,创建逻辑比较简单。与上面的provider函数的constructor参数类似,Angular调用它可以创建服务实例。

使用过滤器格式化数据

语法:{{expression | filterName:parameter1: …parameterN}}

表达式可以是任意的Angular表达式,filterName是你需要使用的过滤器的名称,过滤器的多个参数之间用冒号分隔。

{{10.1 | currency}}对应$10.10

Angular内置的过滤器还有date , number ,uppercase

{{10.1 | currency | number : 0}}对应显示$10

不必受限于内置的过来器,可以自定义过滤器,标题文字首字母大写

<!doctype html><html lang='en' >  <head>    <title>TitleCaps</title>    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>  </head>  <body ng-app='HomeModule' ng-controller="HomeController">   <h1>{{pageHeading | titleCase}}</h1>  <script>    function HomeController($scope) {      $scope.pageHeading = 'behold the majesty of your page title';    }    var homeModule = angular.module('HomeModule', []);    homeModule.filter('titleCase', function() {      var titleCaseFilter = function(input) {        var words = input.split(' ');        for (var i = 0; i < words.length; i++) {          words[i] = words[i].charAt(0).toUpperCase() + words[i].slice(1);        }        return words.join(' ');      };      return titleCaseFilter;    });  </script>  </body></html>

这里写图片描述

使用路由和$location切换视图

$routeProvider

index.html

<!doctype html><html ng-app="AMail">  <head>    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>    <script src='controllers.js'></script>  </head>  <body>    <h1>A-Mail</h1>    <div ng-view></div>  </body></html>

我们仅仅把标题放在里面,然后在用ng-view指令来告诉Angular把视图显示在这儿。
list.html

<table>  <tr>    <td><strong>Sender</strong></td>    <td><strong>Subject</strong></td>    <td><strong>Date</strong></td>  </tr>  <tr ng-repeat='message in messages'>    <td>{{message.sender}}</td>    <td><a ng-href='#/view/{{message.id}}'>{{message.subject}}</a></td>    <td>{{message.date}}</td>  </tr></table>

由于所有视图模板都会被插入到刚才所创建的外壳中,所以可以把它们都编成HTML文档片段。用ng-repeat指令来遍历邮件列表,然后把它们渲染到table中。

我们想实现用户点击一个主题就能被导航到相应的邮件中。我们在URL和message.id之间进行了数据绑定,所以用户点击id=1的邮件就会被导航到/#/view/1。这种根据URL导航的方式叫做深度链接。
detail.html

<div><strong>Subject:</strong> {{message.subject}}</div><div><strong>Sender:</strong> {{message.sender}}</div><div><strong>Date:</strong> {{message.date}}</div><div>  <strong>To:</strong>  <span ng-repeat='recipient in message.recipients'>{{recipient}} </span></div><div>{{message.message}}</div><a href='#/'>Back to message list</a>

为了把这些模板关联到对应的控制器上,我们将会给routeProviderURLrouteProvider将会负责调用控制器和模板。

controllers.js

// Create a module for our core AMail servicesvar aMailServices = angular.module('AMail', []);// Set up our mappings between URLs, templates, and controllersfunction emailRouteConfig($routeProvider) {  $routeProvider.    when('/', {      controller: ListController,      templateUrl: 'list.html'    }).// Notice that for the detail view, we specify a parameterized URL component// by placing a colon in front of the id    when('/view/:id', {      controller: DetailController,      templateUrl: 'detail.html'    }).    otherwise({      redirectTo: '/'    });}// Set up our route so the AMail service can find itaMailServices.config(emailRouteConfig);// Some fake emailsmessages = [{  id: 0, sender: 'jean@somecompany.com', subject: 'Hi there, old friend',  date: 'Dec 7, 2013 12:32:00', recipients: ['greg@somecompany.com'],  message: 'Hey, we should get together for lunch sometime and catch up.'    +'There are many things we should collaborate on this year.'}, {  id: 1,  sender: 'maria@somecompany.com',  subject: 'Where did you leave my laptop?',  date: 'Dec 7, 2013 8:15:12', recipients: ['greg@somecompany.com'],  message: 'I thought you were going to put it in my desk drawer.'    +'But it does not seem to be there.'}, {  id: 2, sender: 'bill@somecompany.com', subject: 'Lost python',  date: 'Dec 6, 2013 20:35:02', recipients: ['greg@somecompany.com'],  message: 'Nobody panic, but my pet python is missing from her cage.'    +'She doesn\'t move too fast, so just call me if you see her.'} ];// Publish our messages for the list templatefunction ListController($scope) {  $scope.messages = messages;}// Get the message id from the route (parsed from the URL) and use it to// find the right message object.function DetailController($scope, $routeParams) {  $scope.message = messages[$routeParams.id];}

与服务器交互

Angular提供$http服务,使得与服务器的交互更加容易。待详解。

<!doctype html><html lang='en' ng-app>  <head>    <title>Shopping Cart</title>    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>  </head>  <body ng-controller="ShoppingController">    <h1>Shop!</h1>    <table>      <tr ng-repeat="item in items">        <td>{{item.title}}</td>        <td>{{item.description}}</td>        <td>{{item.price | currency}}</td>      </tr>    </table>    <script>      function ShoppingController($scope, $http) {        $http.get('/products').success(function(data, status, headers, config) {          $scope.items = data;        });      }    </script>  </body></html>

使用指令修改DOM

<!doctype html><html lang='en' ng-app='app'>  <head>    <title>Get focused</title>    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>  </head>  <body ng-controller="SomeController">    <button ng-click="clickUnfocused()">      Not focused    </button>    <button ngbk-focus ng-click="clickFocused()">      I'm very focused!    </button>    <div>{{message.text}}</div>    <script>      function SomeController($scope) {        $scope.message = { text: 'nothing clicked yet' };        $scope.clickUnfocused = function() {          $scope.message.text = 'unfocused button clicked';        };        $scope.clickFocused = function() {          $scope.message.text = 'focus button clicked';        };      }      var appModule = angular.module('app', []);      appModule.directive('ngbkFocus', function() {        return {          link: function(scope, element, attrs, controller) {            element[0].focus();          }        };      });    </script>  </body></html> 

这里写图片描述

你会看到焦点在第二个按钮上面。

校验用户输入

Angular为表单添加了一些很好用的特性

<!doctype html><html lang='en' ng-app>  <head>    <title>Validate me!</title>    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>    <style type="text/css">    .ng-invalid {      border-color: red;    }    </style>  </head>  <body>    <h1>Sign Up</h1>    <form name='addUserForm' ng-controller="AddUserController">      <div ng-show='message'>{{message}}</div>      <div>First name: <input name='firstName' ng-model='user.first' required></div>      <div>Last name: <input ng-model='user.last' required></div>      <div>Email: <input type='email' ng-model='user.email' required></div>      <div>Age: <input type='number'                       ng-model='user.age'                       ng-maxlength='3'                       ng-min='1'></div>      <div><button ng-click='addUser()'                   ng-disabled='!addUserForm.$valid'>Submit</button></div>    </form>  <script>    function AddUserController($scope) {      $scope.message = '';      $scope.addUser = function () {        // TODO for the reader: actually save user to database...        $scope.message = 'Thanks, ' + $scope.user.first + ', we added you!';      };    }  </script>  </body></html>

这里写图片描述

我们可以通过$valid属性获取表单的校验状态。配合ng-disabled,表单没有输入完成时禁用submit按钮。

SpringMVC AngularJs 交互

angularjs.jsp

<%--  Created by IntelliJ IDEA.  User: fanchengwei  Date: 2016/9/29  Time: 下午2:10  To change this template use File | Settings | File Templates.--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html ng-app="myApp"><!--    ng-app用来告诉Angular页面中的哪部门需要接受它的管理--><head lang="en">    <meta charset="utf-8">    <title>Teams List App</title>    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>    <link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.1/css/bootstrap.min.css">    <script src="http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/2.1.1/bootstrap.min.js"></script>    <script src="webpage/com/kd/business/angularjs/services.js"></script>    <script src="webpage/com/kd/business/angularjs/app.js"></script></head><body><div class="row-fluid">    <div class="span3" ng-controller="FilterCtrl">        <form class="form-horizontal">            <div class="controls-row">                <label for="searchTextBox" class="control-label">Search:</label>                <div class="controls">                    <input type="text" id="searchTextBox" ng-model="filterService.searchText">                </div>            </div>            <div class="controls-row">                <label for="sportComboBox" class="control-label">Sport:</label>                <div class="controls">                    <select id="sportComboBox" ng-model="filterService.activeFilters.sport">                        <option ng-repeat="sport in ['Basketball', 'Hockey', 'Football']">{{sport}}</option>                    </select>                </div>            </div>            <div class="controls-row">                <label for="cityComboBox" class="control-label">City:</label>                <div class="controls">                    <select id="cityComboBox" ng-model="filterService.activeFilters.city">                        <option ng-repeat="city in ['Dallas', 'Los Angeles', 'Boston', 'New York']">{{city}}</option>                    </select>                </div>            </div>            <div class="controls-row">                <label class="control-label">Featured:</label>                <div class="controls">                    <input type="checkbox" ng-model="filterService.activeFilters.featured" ng-false-value="" />                </div>            </div>        </form>    </div>    <div class="offset1 span8" ng-controller="ListCtrl">        <table  border="1">            <thead>            <tr>                <th>key_p</th>                <th>position</th>                <th>responsible_person</th>            </tr>            </thead>            <tbody id="teamListTable">            <tr ng-repeat="team in teamsList | filter:filterService.activeFilters | filter:filterService.searchText">                <td>{{team.key_p}}</td>                <td>{{team.position}}</td>                <td>{{team.responsible_person}}</td>            </tr>            </tbody>        </table>    </div></div></body></html>

app.js

var app = angular.module('myApp', ['myApp.services']);app.controller('ListCtrl', function ($scope, $http, filterService) {    $scope.filterService = filterService;    var url = "angularJsController.do?query";    $http({method: 'GET', url: url}).success(function (list, status, headers, config) {        $scope.teamsList = list;    }).error(function (list, status, headers, config) {        console.log("error");    });});app.controller('FilterCtrl', function ($scope, filterService) {    $scope.filterService = filterService;});

services.js

angular.module('myApp.services', []).  factory('filterService', function() {    return {      activeFilters: {},      searchText: ''    };});

AngularJsController.java

package com.kd.business.angularjs;import com.kd.business.smart_socket.service.ZzSmartsocketServiceI;import com.kd.platform.web.system.service.SystemService;import org.apache.poi.ss.formula.functions.T;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Scope;import org.springframework.http.HttpStatus;import org.springframework.http.ResponseEntity;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.util.List;import java.util.Map;/** * AngularJsController * * @author Frey Fan * @date 2016/9/29 * 测试类AngularJs */@Scope("prototype")@Controller@RequestMapping("/angularJsController")public class AngularJsController {    @Autowired    private ZzSmartsocketServiceI zzSmartsocketService;    @Autowired    private SystemService systemService;    @RequestMapping(params={"init"})    public ModelAndView init(HttpServletRequest request)    {        return new ModelAndView("com/kd/business/angularjs/angularjs");    }    @RequestMapping(params = {"query"})    public ResponseEntity<List<Map<String, Object>>> query(HttpServletRequest request, HttpServletResponse response){        List list = systemService.findForJdbc("select key_p ,position,responsible_person from zz_smartsocket",null);        return new ResponseEntity<List<Map<String, Object>>>(list, HttpStatus.OK);    }}
0 0
原创粉丝点击