AngularJS前端MVC学习计算(三)——AngularJS服务、路由、内置API、jQueryLite

一、服务

AngularJS功效最基本的零部件之一是劳动(Service)。服务为你的施用提供按照职务的意义。服务可以被视为重复使用的执行2个或八个有关职务的代码块。

AngularJS服务是单例对象,那意味惟有二个实例被创造过,服务使用AngularJS的着重注入机制来定义和挂号。

可以把劳务注入模块、控制器和其余服务。

1.壹 、内置服务

普遍的内置服务如下:

$http 发送http请求

$resource 创制二个可以RESTful服务器端数据源交互对象

$window 浏览器的window元素的jQuery包装

$document 浏览器的document成分的jQuery包装

$rootScope 根成效域的走访

$rootElement 根成分的访问

$cacheFactory 提供键/值对停放到对象缓存

$interval 提供对window.setInterval访问

$timeout 提供对window.setTimeout访问

$cookies 提供对浏览器的cookie的读写访问

$animate 提供动画钩子来同时链接到以CSS和JavaScript为底蕴的动画片

1.1.1、浏览器Window服务($window)

引用浏览器的window对象。默许浏览器的window是大局的根对象。

演示代码:

<!DOCTYPE html>
<!--指定angular管理的范围-->
<html ng-app="app01">
    <head>
        <meta charset="UTF-8">
        <title>服务</title>
    </head>
    <body>
        <!--指定控制器的作用范围-->
        <form ng-controller="Controller1" name="form1">
        </form>
        <!--引入angularjs框架-->
        <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            //定义模块,指定依赖项为空
            var app01 = angular.module("app01", []);

            //定义控制器,指定控制器的名称,$scope是全局对象
            app01.controller("Controller1", ['$scope','$window',function($scope,$win) {
                $win.alert("调用window服务的alert方法");
            }]);
        </script>
    </body>
</html>

运作结果:

AngularJS 1

1.1.贰 、发送http请求服务 ($http)

$http服务从AngularJS代码直接与Web服务器举行交互,底层是经过AJAX完成,与jQuery中$.ajax类似

由此$http封装后的艺术:

delete(url,[config]) 发送谓词为delete的异步请求

get(url,[config]) 发送谓词为get的异步请求

head(url,[config])  发送谓词为head的异步请求

AngularJS,jsonp(url,[config]) 发送通过jsonp落成跨域的一块儿请求的伸手

post(url,data,[config]) 发送谓词为post的异步请求

put(url,data[config]) 发送谓词为put的异步请求
骨干用法:
$http({method: ‘GET’, url: ‘/someUrl’}).
success(function(data, status, headers, config) {
}).
error(function(data, status, headers, config) {
});

详尽的布局如下:

AngularJS 2

AngularJS 3

那里运用NodeJS+Express作为后台服务,完毕1个总结的小车管理职能:

cars.js

var express = require('express');
var router = express.Router();
var _= require('lodash');

var cars=[];
cars.push({id:201701,name:"BMW",price:190,speed:"210km/h",color:"白色"});
cars.push({id:201702,name:"BYD",price:25,speed:"160km/h",color:"红色"});
cars.push({id:201703,name:"Benz",price:300,speed:"215km/h",color:"蓝色"});
cars.push({id:201704,name:"Honda",price:190,speed:"170km/h",color:"黑色"});
cars.push({id:201705,name:"QQ",price:130,speed:"210km/h",color:"白色"});

/* Get */
/*获得所有汽车*/
/*url /cars/*/
router.get('/', function(req, res, next) {
    res.json(cars);
});

/*Get*/
/*获得汽车通过id*/
/*url:/cars/:id  */
router.get('/:id', function(req, res, next) {
     //从路径中映射参数,转换成数字
      var id=parseInt(req.params.id);
      var car=_.find(cars,{id:id});
      res.json(car);
});

/*Post*/
/*添加汽车*/
/*url:/cars/car  */
router.post('/car', function(req, res, next) {
      console.log("收到请求");
      var car=req.body;  //从请求正文中获得json对象
      car.id=_.last(cars).id+1;  //将编号修改为最后一辆车的编号+1
      cars.push(car);  //将汽车对象添加到集合中
      res.json(car);  //将添加成功的车以json的形式返回
});

/*Put*/
/*修改汽车*/
/*url:/cars/car  */
router.put('/car', function(req, res, next) {
      var car=req.body;  //从请求正文中获得json对象
      console.log(req.body);
      var index=_.findIndex(cars,{id:parseInt(car.id)});  //根据id获得车在集合中的下标

      cars[index]=car;  //替换原对象
      //res.json(car);  //将修改后的车以json的形式返回
      res.send({status:"success", message:"更新成功!"});  
});

/*Delete*/
/*删除汽车*/
/*url:/cars/:id  */
router.delete('/id/:id', function(req, res, next) {
      //获得url中的编号参数
      var id=parseInt(req.params.id);
      var index=_.findIndex(cars,{id:id});  //根据id获得车在集合中的下标
      cars.splice(index,1);   //在cars数组中删除下标从index开始的1条数据
      res.json(cars);  
});

module.exports = router;

app.js

var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var index = require('./routes/index');
var users = require('./routes/users');
var pdts = require('./routes/product');
var task = require('./routes/task');
var cars = require('./routes/cars');

var app = express();

//指定视图引擎为ejs
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.all('*', function(req, res, next) { 
    res.header("Access-Control-Allow-Origin", "*");  
    res.header("Access-Control-Allow-Headers", "content-type");  
    res.header("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS");  
    res.header("X-Powered-By",' 3.2.1')  
    res.header("Content-Type", "application/json;charset=utf-8");  
    next();  
});  

app.use('/', index);
app.use('/users', users);
app.use('/pdt', pdts);
app.use("/task",task);
app.use("/cars",cars);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

// error handler
app.use(function(err, req, res, next) {
  // set locals, only providing error in development
  res.locals.message = err.message;
  res.locals.error = req.app.get('env') === 'development' ? err : {};

  // render the error page
  res.status(err.status || 500);
  res.render('error');
});

module.exports = app;

www

#!/usr/bin/env node

/**
 * 依赖模块,导入
 */

var app = require('../app');
var debug = require('debug')('nodejsexpress:server');
var http = require('http');

/**
 * 从上下文环境中获得监听端口,如果空则3000
 */

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
 * 创建Web服务器
 */

var server = http.createServer(app);

/**
 * 开始监听
 */

server.listen(port);
server.on('error', onError);  //指定发生错误时的事件
server.on('listening', onListening);  //当监听成功时的回调

/**
 * 规范化端口
 */

function normalizePort(val) {
  var port = parseInt(val, 10);

  if (isNaN(port)) {
    // named pipe
    return val;
  }

  if (port >= 0) {
    // port number
    return port;
  }

  return false;
}

/**
 *错误事件监听
 */

function onError(error) {
  if (error.syscall !== 'listen') {
    throw error;
  }

  var bind = typeof port === 'string'
    ? 'Pipe ' + port
    : 'Port ' + port;

  //错误处理
  switch (error.code) {
    case 'EACCES':
      console.error(bind + ' requires elevated privileges');
      process.exit(1);  //结束程序
      break;
    case 'EADDRINUSE':
      console.error(bind + ' is already in use');
      process.exit(1);
      break;
    default:
      throw error;
  }
}

/**
 * 当用户访问服务器成功时的回调
 */

function onListening() {
  var addr = server.address();
  var bind = typeof addr === 'string'
    ? 'pipe ' + addr
    : 'port ' + addr.port;
  debug('Listening on ' + bind);
}

示范代码:

<!DOCTYPE html>
<!--指定angular管理的范围-->
<html ng-app="carApp">

    <head>
        <meta charset="UTF-8">
        <title>服务</title>
        <style>
            * {
                margin: 0;
                padding: 0;
                font-family: microsoft yahei;
                font-size: 14px;
            }

            body {
                padding-top: 20px;
            }

            .main {
                width: 90%;
                margin: 0 auto;
                border: 1px solid #777;
                padding: 20px;
            }

            .main .title {
                font-size: 20px;
                font-weight: normal;
                border-bottom: 1px solid #ccc;
                margin-bottom: 15px;
                padding-bottom: 5px;
                color: blue;
            }

            .main .title span {
                display: inline-block;
                font-size: 20px;
                background: blue;
                color: #fff;
                padding: 0 8px;
                background: blue;
            }

            a {
                color: blue;
                text-decoration: none;
            }

            a:hover {
                color: orangered;
            }

            .tab td,
            .tab,
            .tab th {
                border: 1px solid #777;
                border-collapse: collapse;
            }

            .tab td,
            .tab th {
                line-height: 26px;
                height: 26px;
                padding-left: 5px;
            }

            .abtn {
                display: inline-block;
                height: 20px;
                line-height: 20px;
                background: blue;
                color: #fff;
                padding: 0 5px;
            }

            .btn {
                height: 20px;
                line-height: 20px;
                background: blue;
                color: #fff;
                padding: 0 8px;
                border: 0;
            }

            .abtn:hover,
            .btn:hover {
                background: orangered;
                color: #fff;
            }

            p {
                padding: 5px 0;
            }

            fieldset {
                margin-top: 10px;
                border: 1px solid #ccc;
                padding: 5px 10px;
            }

            fieldset legend {
                margin-left: 10px;
                font-size: 16px;
            }
        </style>
    </head>

    <body>
        <!--指定控制器的作用范围-->
        <form ng-controller="CarController" class="main">
            <h2 class="title">汽车管理</h2>
            <table border="1" width="100%" class="tab">
                <tr>
                    <th>序列</th>
                    <th>编号</th>
                    <th>名称</th>
                    <th>价格</th>
                    <th>颜色</th>
                    <th>速度</th>
                    <th>操作</th>
                </tr>
                <tr ng-repeat="c in cars">
                    <td>{{$index+1}}</td>
                    <td>{{c.id}}</td>
                    <td>{{c.name}}</td>
                    <td>{{c.price}}</td>
                    <td>{{c.color}}</td>
                    <td>{{c.speed}}</td>
                    <td>
                        <a href="#" ng-click="del(c.id)">删除</a>
                        <a href="#" ng-click="edit(c)">编辑</a>
                    </td>
                </tr>
            </table>
            <fieldset>
                <legend>汽车详细</legend>
                <p>
                    <label for="id">编号</label>
                    <input ng-model="car.id" id="id" ng-readonly="true" />
                </p>
                <p>
                    <label for="name">名称</label>
                    <input ng-model="car.name" id="name" />
                </p>
                <p>
                    <label for="price">价格</label>
                    <input ng-model="car.price" id="price" />
                </p>
                <p>
                    <label for="color">颜色</label>
                    <input ng-model="car.color" id="color" />
                </p>
                <p>
                    <label for="color">速度</label>
                    <input ng-model="car.speed" id="speed" />
                </p>
                <button ng-click="save()" class="btn">保存</button>
                <button ng-click="clear()" class="btn">清空</button>
            </fieldset>
        </form>

        <!--引入angularjs框架-->
        <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            //定义模块,指定依赖项为空
            var carApp = angular.module("carApp", []);

            //定义控制器,指定控制器的名称,$scope是全局对象
            carApp.controller("CarController", ['$scope', '$http', function($scope, $http) {
                $scope.cars = [];
                $scope.save = function() {
                    $http({
                        url:"http://127.0.0.1:3000/cars/car",
                        data:$scope.car,
                        method: $scope.car.id?"PUT":"POST"
                        })
                        .success(function(data, status, headers, config) {
                            if($scope.car.id){
                               alert("修改成功");
                             }else{
                                 $scope.cars.push(data);
                             }
                        })
                        .error(function(data, status, headers, config) {
                            alert(status);
                        });
                }

                $scope.edit=function(c){
                    $scope.car=c;
                }
                $scope.clear=function(){
                    $scope.car={};
                }

                $http.get("http://127.0.0.1:3000/cars")
                    .success(function(data, status, headers, config) {
                        $scope.cars = data;
                    })
                    .error(function(data, status, headers, config) {
                        alert(status);
                    });

                $scope.del = function(id) {
                    $http.delete("http://127.0.0.1:3000/cars/id/" + id)
                        .success(function(data, status, headers, config) {
                            $scope.cars = data;
                        })
                        .error(function(data, status, headers, config) {
                            alert(status);
                        });
                }
            }]);
        </script>
    </body>

</html>

运作结果:

AngularJS 4

标题:假设后台服务不是Restful,不接收application/json的参数,则须要修改。Angular的post和put请求Content-Type:
application/json暗许意况下,jQuery传输数据选用Content-Type:
x-www-form-urlencodedand和好像于”foo=bar&baz=moe”的行列,不过AngularJS,传输数据使用Content-Type:
application/json和{ “foo”: “bar”, “baz”: “moe”
}那样的json体系。请求时修改请求尾部内容:

headers: { ‘Content-Type’: ‘application/x-www-form-urlencoded;
charset=UTF-8’ }

$httpParamSerializerJQLike 种类化参数,那一个服务需求独自倚重。

示例:

AngularJS 5

AngularJS 6

结果:

AngularJS 7

1.1.3、AngularJS Crome插件

AngularJS Batarang是三个突显AngularJS的scope
层次的Chrome插件,有效的高效查看1个page
中有些许Scope可以协理大家快捷方便调试AngularJS程序。

AngularJS 8

1.二 、自定义服务

AngularJS在置放服务中提供了多量的功能,然而这个劳务不肯定能满足你的急需,你可以通过自定义服务消除。能够将服务作为八个或三个有关义务的一块可采用代码。

开创自定义服务有4种主要品种:value,constant,factory,service

1.2.1、创建value服务

概念单个值的简练劳动,模块的配置阶段是不能够使用的。
module.value(‘key’,{color:’blue’,value:’17’})

1.2.2、创建constant服务

也value服务均等,但是在模块的陈设阶段是可以使和的。

module.value(“key”,”value”);

1.2.3、创建factory服务

提供了把效益完结到服务中的能力。

也得以把别的服务注入到factory中。

AngularJS 9

1.2.4、创建Service服务

factory是普通function,而service是五个构造器(constructor),这样Angular在调用service时会用new关键字,而调用factory时只是调用普通的function,所以factory可以回来任李强西,而service可以不回来

示范代码:

<!DOCTYPE html>
<!--指定angular管理的范围-->
<html ng-app="app01">
    <head>
        <meta charset="UTF-8">
        <title>服务</title>
    </head>
    <body>
        <!--指定控制器的作用范围-->
        <form ng-controller="Controller1" name="form1">
            <p>
                半径:<input ng-model="r" ng-init="r=1"/>
            </p>
            <p>
                周长:{{circleLength}}
            </p>
            <p>
                面积:{{circleArea}}
            </p>
        </form>
        <!--引入angularjs框架-->
        <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            //定义模块,指定依赖项为空
            var app01 = angular.module("app01", []);

            //value服务
            app01.value("i",100);

            //constant服务
            app01.constant("PI",3.14);

            //factory服务
            app01.factory("getArea",['i','PI',function(i,PI){
                return function(radius){
                    return PI*(radius+i)*(radius+i);
                };
            }])

            function circleMethod(i,PI,getArea){
                this.getLength=function(radius){
                    return 2*PI*radius;
                };
                this.getSize=function(radius){
                    return getArea(radius);
                }
            }
            //service服务
            app01.service("circleService",circleMethod);

            //定义控制器,指定控制器的名称,$scope是全局对象
            app01.controller("Controller1", function($scope,circleService) {
                $scope.$watch("r",function(){
                    $scope.circleLength=circleService.getLength($scope.r);
                    $scope.circleArea=circleService.getSize($scope.r);
                });
            });
        </script>
    </body>
</html>

运作结果:

AngularJS 10

二、路由

单页Web应用由于并未后端U奥德赛L财富一定的支撑,必要协调完结U奥德赛L财富一定。angularjs使用浏览器U瑞鹰L
“#” 后的字符串来恒定财富,区分不相同的功效模块。
路由并非在angularjs大旨文件内,你要求此外参与一段脚本
“angular-route.min.js”须要专注的是在创造 “app” 对象是索要填写对 ngRoute
看重

以身作则代码:

routeTest.html 单页程序的首页

<!DOCTYPE html>
<html ng-app="app">

    <head>
        <meta charset="utf-8">
        <title>路由展示</title>
        <style>
            a {
                color: #333;
                text-decoration: none;
            }

            a:hover {
                color: orangered;
            }
        </style>
    </head>

    <body>
        <p>
            <a href="#/">返回列表</a>
            <a href="#/t1">当前时间</a>
            <hr />
        </p>
        <div ng-view></div>
        <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script>
        <script src="js/angular146/angular-route.min.js" type="text/javascript" charset="utf-8"></script>
        <script id="t1" type="text/ng-template">
            当前时间是:{{currentDate}}
        </script>
        <script type="text/javascript">
            var app = angular.module("app", ['ngRoute']);
            app.config(function($routeProvider) {
                $routeProvider.when('/', {
                    controller: 'listController',
                    templateUrl: 'list.html'
                });
                $routeProvider.when('/t1', {
                    controller: 't1Controller',
                    templateUrl: 't1'
                });
                $routeProvider.when('/detail/:id', {
                    controller: 'detailController',
                    templateUrl: 'detail.html'
                });
                $routeProvider.otherwise({
                    redirectTo: '/'
                });
            });
            app.service("dataService", function() {
                this.list = [{
                    id: 1,
                    title: '谷歌',
                    url: 'http://www.google.com'
                }, {
                    id: 2,
                    title: '百度',
                    url: 'http://www.baidu.com'
                }, {
                    id: 3,
                    title: '必应',
                    url: 'http://www.bing.com'
                }, {
                    id: 4,
                    title: '搜狗',
                    url: 'http://www.sogou.com'
                }, {
                    id: 5,
                    title: '雅虎',
                    url: 'http://www.yahoo.cn'
                }];
                this.getEntity = function(id) {
                    var result = null;
                    angular.forEach(this.list, function(obj, index) {
                        if(obj.id == id) {
                            result = obj;
                        }
                    });
                    return result;
                }
            });
            app.controller("listController", function($scope, dataService) {

                $scope.items = dataService.list;
            });
            app.controller("detailController", function($scope, dataService, $routeParams) {

                $scope.obj = dataService.getEntity($routeParams.id);
            });
            app.controller("t1Controller", function($scope) {
                $scope.currentDate = new Date().toLocaleString();
            });
        </script>
    </body>

</html>

列表页 list.html

<ul ng-repeat="item in items">
    <li>
        <a href="#/detail/{{item.id}}">{{item.title}}</a>
    </li>
</ul>

详细页 detail.html:

<fieldset>
    <legend>详细信息</legend>
    <p>
        编号:{{obj.id}}
    </p>
    <p>
        名称:{{obj.title}}
    </p>
    <p>
        网址: <a href="{{obj.url}}">{{obj.url}}</a>
    </p>
</fieldset>

运作结果:

AngularJS 11

AngularJS 12

AngularJS 13

三、内置API

3.① 、数据转换

AngularJS 14

示例:

暗中认同景况JavaScript中目的是传引用的:

                var tom={name:"tom",age:18,height:198};
                var tomClone=tom;

                tomClone.name="superTom";

                console.log(tom);
                console.log(tomClone);

结果:

AngularJS 15

修改后的以身作则:

                var tom={name:"tom",age:18,height:198};
                var tomClone=tom;
                var tome={}
                angular.copy(tom,tome);

                tomClone.name="superTom";

                console.log(tom);
                console.log(tomClone);
                console.log(tome);

修改后的结果:

AngularJS 16

3.2、JSON相关API

AngularJS 17

3.③ 、数据相比较API

AngularJS 18

四、jQuery Lite

jQuery Lite只是jQuery的二个简化版本,它一贯内置于AngularJS中。

支撑的jQuery方法如下,但多少措施在效益上绝不全盘平等。

addClass after append attr bind children clone
contents css data detach empty eq find hasClass
html text on off one parent prepend prop ready
remove removeAttr removeClass removeData replaceWith toggleClass
triggerHandler unbind
val wrap
叠加事件措施:$destory,controller(name),injector,Scope,isolateScope,inheritedData()

固然要求动用jQuery完整版本的附加成效,那么可以在加载AngularJS库以前引入jQuery库。
<script src=jquery.min.js>
<script src=angular.min.js>
在自定义指令中link:function(scope,elem,attrs,controller) elem is a
jQuery Lite对象

采取时必然要记得将DOM对象转换到jQuery Lite对象

演示代码:

<!DOCTYPE html>
<!--指定angular管理的范围-->
<html ng-app="app01">
    <head>
        <meta charset="UTF-8">
        <title>jQueryLite</title>
    </head>
    <body>
        <!--指定控制器的作用范围-->
        <form ng-controller="Controller1" name="form1">
            <div id="div1" style="height:100px;background: lightgreen;">jQueryLite</div>
        </form>
        <!--引入angularjs框架-->
        <script src="js/angular146/angular.min.js" type="text/javascript" charset="utf-8"></script>
        <script type="text/javascript">
            //定义模块,指定依赖项为空
            var app01 = angular.module("app01", []);

            //定义控制器,指定控制器的名称,$scope是全局对象
            app01.controller("Controller1", ['$scope','$window',function($scope,$win) {

                var div1=document.querySelector("#div1");
                var adiv1=angular.element(div1);
                adiv1.on("click",function(){
                    adiv1.css({"background":"lightblue"}).html("Hello "+adiv1.html());
                    adiv1.off();
                });

            }]);
        </script>
    </body>
</html>

运维结果:

AngularJS 19

AngularJS 20

五、zeptojs

zeptojs是一轻量版的jQuery,拥有多数的jQuery成效,但体量要小很多,gzip后唯有约9.6k。

官网:http://zeptojs.com/

仓库:https://github.com/madrobby/zepto

安装:npm install zepto

AngularJS 21

浏览器协理:

  • Safari 6+ (Mac)
  • Chrome 30+ (Windows, Mac, Android, iOS, Linux, Chrome OS)
  • Firefox 24+ (Windows, Mac, Android, Linux, Firefox OS)
  • iOS 5+ Safari
  • Android 2.3+ Browser
  • Internet Explorer 10+ (Windows, Windows Phone)

WebAPI域

① 、新建4.5版以上的WebAPI项目

2、安装Microsoft.AspNet.WebApi.Cors

Install-Package Microsoft.AspNet.WebApi.Cors

AngularJS 22

3、修改app_start目录下的WebApiConfig.cs文件,扩充如下代码:

            //第1*表示域 如www.abc.com
            //第2*表示允许的头部
            //第3*表示方法(谓词)
            config.EnableCors(new EnableCorsAttribute("*", "*", "*"));

肆 、借使只想控制某三个控制器,则能够应用注明,脾气。

    [EnableCors("*","*","*")]
    public class ValuesController : ApiController

陆 、示例下载

后台服务:https://git.coding.net/zhangguo5/NodeJSExpress.git

前端脚本:https://github.com/zhangguo5/Angular03.git

相关文章