Angular入门学习第二天
Angular的控制器:
1:Angular中用于进行数据逻辑处理和操作的一个模块
2.通过controller()函数进行注册 控制器中的参数$scope,这个参数不需要赋值,angular会自动给$scope参数传递一个数据进行使用
3.控制器:主要用来通过$scope挂载数据、挂载处理函数
2.通过controller()函数进行注册 控制器中的参数$scope,这个参数不需要赋值,angular会自动给$scope参数传递一个数据进行使用
3.控制器:主要用来通过$scope挂载数据、挂载处理函数
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/lib/AngularJS/angular.min.js"></script>
<!--
ng-app是Angular运行的入口
程序引导启动——启动项目——启动HTML页面
首先引导启动根模块——找到ng-app,加载ng-app对应的模块
引导启动模块下的控制器—— 加载模块下面的控制器
ng-app执行的过程
底层——通过bootstrap进行了引导启动@!
-->
</head>
<body>
<!-- 通过ng-app指令进行应用的引导启动:推荐的方式,项目中常用的方式 -->
<div ng-app="myApp1">
<div ng-controller="myCtrl">
{{name}}
<button ng-click="startApp2()">点击启动myApp2模块</button>
</div>
</div>
<div id="startUp">
<div ng-controller="myCtrl">
{{name}}
</div>
</div>
<script>
var app1 = angular.module("myApp1", []);
app1.controller("myCtrl", function($scope) {
$scope.name = "hello start myApp1";
$scope.startApp2 = function() {
console.log("**********");
// 启动第二个模块
var _startUp = document.getElementById("startUp");
angular.bootstrap(_startUp, ["myApp2"]);
}
});
var app2 = angular.module("myApp2", []);
app2.controller("myCtrl", function($scope) {
$scope.name = "hello start from bootstrap!";
});
</script>
</body>
</html>
$scope的作用域.
ng-controller指令是作用域创建指令,当在DOM树中遇到作用域创建指令时,AngularJs都会创建Scope类的新实例$scope.新创建的作用域实例$scope会拥有$parent属性,并指向它的父作用域.在DOM树中,会有很多这样的指令创建出很多作用域
.
$watch监听事件:
var app = angular.module("myApp", []); app.controller("myCtrl", function($scope) { $scope.username = "administrator"; $scope.name = "tom"; $scope.age = 48; $scope.users = { username:"admin", password:"123" } $scope.goodses = [ {goodsID:1, goodsName:"商品A"}, {goodsID:2, goodsName:"商品B"}, {goodsID:3, goodsName:"商品C"} ] // 1. 监听单个普通变量 $scope.$watch("name", function() { // TODO name属性发生变化执行的函数代码 }) // 2. 监听多个变量 $scope.$watch("name + age", function() { // TODO name或者age变量的数据发生变化执行的函数代码 }) // 3. 监听对象的数据 $scope.$watch("users.username", function() { // TODO usres对象中的username属性一旦发生变化执行的函数代码 })
function b(){ //方法1 $scope.b='b'; $scope.$apply(); //方法2 /**$scope.$apply(function(){ $scope.b='b'; })**/ }
// 4. 监听对象的所有属性 $scope.$watch("users", function() { // TODO 监听users对象的所有属性,任一属性值发生变化执行函数代码 },true) // 5. 监听数组数据~而不监听数组中的对象数据 $scope.$watchCollection("goodses", function() { // TODO 一旦goodses数组中的元素,被删除、添加时执行函数的代码 }) // 6. 监听数据发生变化的细节:修改前 VS 修改后 $scope.$watch("username", function(newValue, oldValue) { console.log("数据被修改了", newValue, oldValue); }) // 7. $watch可以重复,不会被覆盖,都会执行! $scope.$watch("username", function(newValue, oldValue) { console.log("data changed:", newValue, oldValue); }) }); /* $scope对象上,有一个$watch()函数,用于监听模型数据的变化 */angular js的双向数据绑定,在开发中起到的作用灰常大,但是,并不是所有时候都能起作用。
找了下资料发现,双向数据绑定其实也就是当模型发生了变化的时候,重绘了DOM,使你看到数据被更新了,引发模型变化的情况有:
1,dom事件;
2,xhr响应触发回调;
3,浏览器的地址变化;
4,计时器触发回调;
以上的某一个情况发生,都会触发模型监控机制,同时调用了$apply方法,重绘了dom;通常情况下,我们使用的一些指令或服务,如$http,$timeout,$location等都会调用$apply方法,
从而使用dom被重绘,数据得到更新,实现了双向数据绑定。
而在有些情况下,比如回调里,
回调函数里执行的方法被不会触发$apply方法。假如当你点击打了比较input select radio等等,触发了模型监控,值也随之更新了。
此时需要手动调$scope方法,使dom重绘。
为了方便多个控制器中的公共数据初始化function b(){ //方法1 $scope.b='b'; $scope.$apply(); //方法2 /**$scope.$apply(function(){ $scope.b='b'; })**/ }
AngularJS提供了一个全局作用域对象$rootScope
AngularJS应用中,仅有一个全局作用域,其他所有的$scope作用域都是$rootScope的子元素
*/
/*
使用$rootScope,可以用于初始化全局变量和函数
但是存在一个问题: 因为控制器函数中可以直接使用$rootScope,就有可能会造成全局数据污染
规范:$rootScope一般和Angular模块的run()方法一起使用。来进行全局数据的初始化
AngularJs的依赖注入
1.隐式注入:不需要开发人员干预,AngularJs自动根据参数的名称进行识别和注入数据.
隐式注入如果一旦优化就会存在问题. 所以我学习了方便后续开发的用的显式注入.
2.显式注入:开发人员通过字符串描述,告诉Angular需要注入的对象名称,这样JS在进行优化的过程,对字符串是不会压缩的.
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/lib/AngularJS/angular.min.js"></script>
</head>
<body>
<div ng-controller="myCtrl">
<span ng-bind="greeting"></span>
</div>
<script>
var app = angular.module("myApp", []);
/*app.controller("myCtrl", function($scope) {
$scope.greeting = "hello controller!";
});*/
app.controller("myCtrl", ["$scope", function($scope) {
$scope.greeting = "这是显式注入的方式"
}]);
</script>
购物车升级版
<!DOCTYPE html> <html ng-app="shop"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="../Angular购物车进阶/js/lib/bootstrap-3.3.7-dist/css/bootstrap.min.css"> <script src="../Angular购物车进阶/js/lib/angular-1.6.4/angular.min.js"></script> </head> <body> <div class="container" ng-controller="shopping"> <div class="row"> <div class="page-header"> <h2>我的购物车</h2> </div> </div> <div class="row"> <div class="col-md-8 col-md-offset-2"> <table class="table table-hover table-striped"> <tr> <th>商品编号</th> <th>商品名称</th> <th>商品单价</th> <th>购买数量</th> <th>小计金额</th> <th>操作</th> </tr> <tr ng-repeat="goods in goodses"> <td><span ng-bind="goods.goodsID"></span></td> <td><span ng-bind="goods.goodsName"></span></td> <td >¥<span ng-bind="goods.goodsPrice"></span></td> <td><input type="text" ng-model="goods.count"></td> <td>¥<span ng-bind="goods.goodsPrice*goods.count"></span></td> <td><button ng-click="remove($index)">移除</button></td> </tr> </table> </div> </div> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-body text-right"> <button ng-click="removeAll()">清空购物车</button></span> </div> </div> </div> </div> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-body text-right"> 总计金额: ¥<span ng-bind="totalQuantity()"></span> </div> </div> </div> </div> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-body text-right"> 运费金额: ¥<span ng-bind="freight()"></span> </div> </div> </div> </div> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-body text-right"> 实付金额: ¥<span ng-bind="totalQuantity()+freight()"></span> </div> </div> </div> </div> </div> <script> var app = angular.module("shop",[]); app.controller("shopping",["$scope",function ($scope) { $scope.goodses = [ {goodsID: 1, goodsName: "商品A", goodsPrice: 130, count: 1, subtotal: 130}, {goodsID: 2, goodsName: "商品B", goodsPrice: 20, count: 1, subtotal: 20}, {goodsID: 3, goodsName: "商品C", goodsPrice: 10, count: 1, subtotal: 10}, {goodsID: 4, goodsName: "商品D", goodsPrice: 30, count: 1, subtotal: 30}, {goodsID: 5, goodsName: "商品E", goodsPrice: 50, count: 1, subtotal: 50}, {goodsID: 6, goodsName: "商品F", goodsPrice: 200, count: 1, subtotal: 200}, ]; $scope.totalQuantity = function(){ var total = 0 for(var i = 0 ; i <$scope.goodses.length;i++ ){ total += $scope.goodses[i].count * $scope.goodses[i].goodsPrice; } return total; } $scope.freight = function () { var fret = 0; var total = 0 for(var i = 0 ; i <$scope.goodses.length;i++ ){ total += $scope.goodses[i].count * $scope.goodses[i].goodsPrice; } if(total<=100){ fret = 10; }else if(total<=200){ fret = 20;; }else if(total<=500){ fret = 30; }else{ fret = 0; } return fret; } $scope.remove = function(index){ if(confirm("确定要清空数据吗")){ $scope.goodses.splice(index,1) } } $scope.removeAll = function(){ if(confirm("确定要清空购物车吗")){ $scope.goodses = []; } } // $scope.payAmount = function () { // var amount = 0 // amount = $scope.total + $scope.fret; // return amount; // } }]) </script> </body> </html>