AngularJS总结

AngularJS

AngularJS是一个开源的网页应用程序的JS框架,由google和一些独立的开发者共同维护,适用于数据操作比较频繁的SPA(Single page application)

AngularJS的4个特点:
  1、采用了MVC的设计模式:
  2、双向数据绑定:
  3、依赖注入:
  4、模块化设计:

一、采用了MVC的设计模式:

  Model:模型数据
  View:视图
  Controller:控制器
  MVC工作方式:通过操作视图,触发控制器指定的方法,拿到
数据给模型,通过绑定显示在视图中去更新视图。

1、常用表达式与指令

  {{}}:直接在页面中显示{{}}中表达式的运算结果
  ng-init:用于直接在元素上初始化变量值,如以下代码在页面中的显示为Jack

<span ng-init="name='Jack'">{{name}}</span>

  ng-repeat:用于遍历数组或对象

<li ng-repeat="tmp in list">{{tmp}}</li>
<li ng-repeat="(key,value) in car">
   {{"key is "+key+" value is "+value}}
</li>

  ng-if:用于判断条件,满足则执行相对应的指令
  ng-show:值为true则显示相应的View
  ng-hide:值为true则隐藏相应的View
  ng-click:触发元素click事件
  

2、MVC简单实现:

1)创建一个模板:

var app=angular.module('模块名称',['依赖列表'])

2)调用模块

<html ng-app="模块名称"></html>

3)创建控制器

app.controller('myCtrl',function($scope){
  //*控制器被调用时执行的方法* 
  $scope.count=0;
  $scope.add=function(){count++;}
})

4)调用控制器

<ANY ng-controller='myCtrl'></ANY>

5)模型数据
$scope服务(对象),是一个作用域控制对象,将模型数据定义在$scope中,可供$scope所属ControllerView调用
6)视图
模型数据在View中显示

<div ng-controller="myCtrl">
 <p>{{count}}</p>
<button ng-click="add()">点我计数</button>
</div>

量的方式:
  ①ngInit
  ②在控制器中通过$scope定义
  建议使用第二种方式,实现结构与行为分离
 

3、自定义指令

自定义指令方法: app.directive('指令名称',fn)

app.directive('drtName',function(){
    return {
      template:'<p> Hello Directive </p>',  //*指定指令要显示的内容*
      restrict:'EACM',                      //*指令的权限*
      replace:true                          //*替换内容,用在指令作为注释的时候使用*
    }
  })

restrict:EElement)、AAttribute)、C(Class)、Mcomment

4、过滤器

AngularJS中过滤器可用于对Model进行筛选、过滤、格式化,再显示到View中
语法:{{表达式|过滤器1:’参数’|过滤器2:’参数’}}
常用过滤器:
    currency:货币样式的格式化
    data:日期做处理
    ppercase:转换为大写
    lowercase:转换为小写
    orderBy:对指定Model进行排序,升序|降序
    limitTo:限定数组中元素的个数
    number:指定小数显示点

  <!--将price添加¥前缀-->
  <p>{{price | currency:'¥'}}</p>  
  <!--将日期转化为指定格式-->
  <p>{{nowDate | date:"yy-MM-dd"}}</p>
  <!--将name转化为指定的格式-->
  <p>{{name | uppercase}}</p>
  <p>{{name | lowercase}}</p>
  <!--将数组根据name进行降序排序-->
  <ul>
    <li ng-repeat="tmp in list  | orderBy:'name':true track by $index">
      {{tmp.age +" "+tmp.name }}
    </li>
  </ul>
  <!--限制repeat的数量为2-->
  <ul>
    <li ng-repeat="tmp in list | limitTo:2">
      {{tmp.age +" "+tmp.name }}
    </li>
  </ul>
</div>

二、双向数据绑定:

1、方向一:Model –> View

  点击button,控制器中的funcClick函数使$scope.num不断加一,经过Angular的方向一上的绑定,页面中p标签的num也不断加一

<div ng-controller="myCtrl">
  <p>{{num}}</p>
  <button ng-click="funcClick()">clickMe</button>
</div>
<script>
  var app = angular.module('myModule',['ng']);
  app.controller('myCtrl', function ($scope) {
    console.log(' in myCtrl ');
    $scope.num = 10;
    $scope.funcClick = function(){
      console.log(' button is pressed ');
    }
  })
</script>
2、方向二:View(通常表单输入) –>Model

  在表单元素上使用ng-model绑定”inputTxt变量”,一旦input中输入的变量发生变化,$scope.inputTxt的值也会发生相应的变化,所以<p>{{inputTxt}}</p>中的值也会同步于input表单的输入值发生变化。此时产生了两个方向上的数据绑定:

  • View->Model(输入值到inputTxt)
  • Model->View(inputTxt到p标签)
<div ng-controller="myCtrl">
  <input type="text" ng-model="inputTxt"/>
  <p>{{inputTxt}}</p>
</div>
<script>
  var app = angular.module('myApp', ['ng']);
  app.controller('myCtrl', function ($scope) {
    ...
  });
</script>
3、$watch实现对View的动态监听

在AngularJS中可以使用$scope.$watch(model,callback)对相应的model变化进行监听,倘若model发生变化,则执行相对应的callback

<div ng-controller="myCtrl">
   <input type="text" ng-model="inputTxt"/>
   <p>{{inputTxt}}</p>
</div>
<script>
   var app = angular.module('myApp', ['ng']);
   app.controller('myCtrl', function ($scope) {
       $scope.$watch('inputTxt',function(){   //使用$scope.$watch监听inputTxt的值
       console.log($scope.inputTxt);
       })
    });
  </script>

三、服务

AngularJS中服务指的是一些函数或者对象,可以在整个应用中持有某些行为和状态。控制器虽然有状态,但是并不稳定,可能被多次销毁和重建,所以需要引入服务,而每一个服务都是以一个单例存在

1、控制器间通信:

1)通过$rootScope实现控制器间相互访问
不同的控制器有着不同的作用范围对象,是相互隔离的,是不能直接相互调用的。每一个Angular应用会有一个根作用域$rootScope,在ng启动时初始化id=1,依赖注入的各个控制器的$scope都是$rootScope的子元素。所以可以通过将数据放在$rootScope下进行共享各个控制器间的数据。

<div ng-controller="myCtrl01">
  <p>{{"ctrl01 "+num}}</p>     <!--显示"ctrl01 10"-->
</div>

<div ng-controller="myCtrl02">
  <p>{{"ctrl02 "+num}}</p>     <!--显示"ctrl02 100"-->
  <p>{{"ctrl02 "+school}}</p>  <!--显示"ctrl02 Combridge"-->
</div>

<script>
  var app = angular.module('myApp', ['ng']);
  app.controller('myCtrl01', function ($scope,$rootScope) {
    $scope.num = 10;
    console.log($scope);     //$scope id 为 2
    console.log($rootScope); //$rootScope id 为 1
    $rootScope.school='Combridge';
  });
  app.controller('myCtrl02', function ($scope) {
    console.log($scope);     //$scope id 为 3
    $scope.num = 100;
  });
</script>

2)子元素的可以访问到父元素$scope下的属性和方法

<body ng-controller="parentCtrl">
<div ng-controller="myCtrl01">
    <button ng-click="funcClick()">clickMe01</button>
</div>
<div ng-controller="myCtrl02">
    <button ng-click="funcClick()">clickMe02</button>
</div>
<script>
    var app=angular.module('myApp',['ng']);
    app.controller('parentCtrl',function($scope){
        $scope.funcClick=function () {
            console.log("parentCtrl 被点击了");
        }
    });
    app.controller('myCtrl01',function($scope){});
    app.controller('myCtrl02',function($scope){});
</script>

3)通过事件发射实现Controller之间的通信:

  • 将事件从父传递给子:$scope.$broadcast(eventName,data)

  • 将事件从子传递给父:$scope.$emit(eventName,data);

  • 接受事件以及传递的参数:$scope.$on(eventName,function(event,data){})

<div ng-controller="myCtrl01">
    <button ng-click="callChild()">调用子控制器</button>
    <div ng-controller="myCtrl02">
        <button ng-click="toChild()">传递数据给子控制器</button>
        <div ng-controller="myCtrl03"></div>
    </div>
</div>
<script>
    var app=angular.module('myApp',['ng']);
    app.controller('myCtrl01',function ($scope) {
        $scope.$on('event_1',function(event,data){  //接收子元素发送的event_1
            console.log(data);
            $scope.callChild=data;
        })
    });
    app.controller('myCtrl02',function ($scope) {
        $scope.toParent =function () {
            console.log('toParent method is called ');
        }
        /*向父元素发送event_1*/
        $scope.$emit('event_1',$scope.toParent);
        $scope.toChild=function () {
        /*向子元素发送event_2*/
            $scope.$broadcast('event_2',"Hello myCtrl03");             
        }
    });
    app.controller('myCtrl03',function($scope){
        $scope.on('event_2',function(event,data){
            console.log(data);
        });
    })
</script>
2、定时器和计时器

1)原生定时器和计时器
  在AngularJS中使用Interval定时器,改变一个Model不会刷新其绑定的View,其原因在于AngularJS的本身循环与原生JS定时器有一个冲突。由双向绑定可知,当我们去做数据绑定时,ng框架会自动地给数据添加一个监听watcher,ng中存在一个$digest方法会周期性地检查模型数据是否发生了变化,每当模型数据发生变化时,就对应有一个回调,更新View。通常ngClick、ngSrc会触发$digest,也可通过手动执行($scope.$digest)。

    <div ng-controller="myCtrl"><p>{{num}}</p></div>
    <script>
        var app=angular.module('myApp',['ng']);
        app.controller('myCtrl',function($scope){
            $scope.num=0;
            setInterval(function(){
                $scope.num++;
                console.log($scope.num);
                /*当不添加$digest时,num会增加,但不会刷新页面*/
                /*也可以使用$scope.$apply()代替$scope.$digest()*/
                $scope.$digest();  
            },1000);
        })
    </script>

2)$interval$timeout

AngularJS提供了$interval(callback)和$timeout(callback)用于专门的定时和计时操作,在使用前需要注入app.controller('myCtrl',function($scope,$interval,$timeout){});

$interval(function () {   //执行回调
      $scope.num++;
},1000)
$timeout(function () {    //执行回调
      $scope.num++;
},1000)

取消定时器和计时器:$interval.cancel("定时器名")、$timeout.cancel("计时器名")

3、$http服务

1)get请求方式:$http.get $http({methd:'get',url:''})

$http.get('data/test.json').success(function(data){
            $scope.studList=data;
        })

2)post请求方式:$http.post $http({methd:'post',url:'',data:''})

$http({method:"post",url:"data/test.php"})
                .success(function(data){  //成功,data接受数据
                    console.log(data);
                    $scope.studList=data;
                })
                .error(function(error){   //失败,error获取错误
                    console.log(error);
                });

注意:采用post请求服务时,需要初始化设置“Content-Type”:

app.run(function ($http) {
        $http.defaults.headers.post = {'Content-Type':'application/x-www-form-urlencoded'};
    })
4、自定义服务

1)借助内置的$provide服务

angular.module('myApp',['ng'],function($provide){
    //自定义服务
    $provide.factory/service/constant/value
})

2)调用模块中的注册方法:factory、service、constant、value
factory:callback直接返回一个对象

app.factory('服务名称',function(){
    return {
        //返回的属性或方法
    }
})

service:function为一个构造函数

app.service('服务名称',function(){
    this.name = "";
    this.funcCall = function(){}
})

constantvalue:对于constant和value所创建的服务,可以通过angular.extend去完成数据的重置

app.constant("服务名称",{})
app.value("服务名称",{})

四、依赖注入

AngualrJS中的服务非常依赖于它的注入系统。任何已有的AngularJS服务都能轻易地通过将它定义为一种依赖来注入到其他服务、指令或者控制器中。依赖注入可以增强代码的重用性、模块化和可测试性,它仅仅是声明而不是创建出所依赖的服务实例,

1、安全地注入:

myModule.controller('MainCtrl',['$log',function($log){}]),当然前面我们采用了另外一种更简便的注入方式myModule.controller('MainCtrl',function($log){})。这里我们推荐采用前一种,原因在于,当我们构建完一个应用并进行部署时,通常会进行压缩,所有的JS聚合到一个单一的文件中,注释都被去掉,变量被缩短,导致$log可能变成a这样的简单表示方式,从而失去与原服务的联系。

2、顺序注入:

myModule.controller("MainCtrl",["$log","$window",function($w,$l)])中测试可发现$w代表了$log$l代表了$window,说明形参的引用与注入的顺序是一一对应的

3、标记式注入:

使用$inject属性来完成标记,该属性是以一个字符型ctrFunc.$inject = ["$scope","$write"];
注意项:在数组中服务的先后的顺序 要和 控制器的回调中服务的先后顺序要保持一致

4、$injector的使用:

has(“服务名称”): 判断指定的服务是否存在
get(“服务名称”): 得到一个存在的服务的实例对象
两种使用方案:

  • 创建一个ng对象的时候,注入$injector
  • angular.injector()
    var injector=angular.injector(["ng","myApp"]);
    if(injector.has("$custom")){
        var custom=injector.get("$custom");
        custom.print();
    }

五、模块化设计

1、模块的调用

在创建模块A的时候,指定模块B写在模块A的依赖列表中
angular.module(‘moduleA’,[‘moduleB’])
一个AngularJS模块一般都由什么构成?

  • Service:提供某种对象(变量、方法)
  • Controller:控制Model操作
  • Directive:绑定Model和View
  • Function:完成指定功能
  • Filter:过滤、筛选、格式化
<body ng-controller="myCtrl02">
<button ng-click="funcPrint()">clickMe</button>
<script>
    var app01=angular.module('myApp01',['ng']);
    app01.factory('$custom',function(){
        return{
            print:function(){
                console.log('$custom服务中的方法被调用了')
            }
        }
    })
    var app02=angular.module('myApp02',["myApp01"]);
    app02.controller('myCtrl02',["$scope","$custom",
        function($scope,$custom){
            $scope.funcPrint=function(){
                $custom.print();
            }
        }
    ])
</script>
2、ngRoute模块实现SPA

SPA工作原理
URL地址:http://127.0.0.1/index.html#/路由地址

  • 请求完整的页面地址 index.html
  • 解析地址 拿到 ‘#’后面的 路由地址
  • 查询路由字典,根据路由地址,找到真实的模板页面的地址
  • 发起ajax请求,加载模板页面,插入到DOM

AngularJS中实现SPA的步骤:

  • 创建完整的html页面,引入angular.js angular-route.js

    <script src="js/angular-route.js"></script>
    
  • 创建模块,指定依赖于 ng ngRoute,通过ng-app调用模块

    var app = angular.module('myApp',['ng','ngRoute']);
    
  • 指定一个容器用来盛放代码片段 ngView

    <div ng-iew=""></div>
    
  • 创建模板页面
    tpl/1.hyml:<div>This is the first page</div>
    tpl/2.html:<div>This is the second page</div>
    tpl/3.html:<div>This is the third page</div>
  • 配置路由词典

    app.config(function($routeProvider){
        $routeProvider
                .when("/first",{controller:'',templateUrl:'tpl/1.html'})
                .when("/second",{controller:'',templateUrl:'tpl/2.html'})
                .when("/third",{controller:'',templateUrl:'tpl/3.html'})
                .otherwise({redirectTo:'/start'});  /*URL中没有路由或出现无效路由则自动重定向到/start页面*/
    })
    
  • 发起路由跳转:
      直接修改地址栏中的路由地址
      超链接 <a href='#/myStart'></a>
      js来实现跳转$location.path('/myStart');

AngularJS模板页面间实现传参步骤:

  • 明确发送方和接收方

    发送:login
    接收:main

  • 接收方的配置
    通过注入$routeParams,然后通过$routeParam.id读取参数

$routeProvider.when('/myMain/:id',{
    controller:''
    templateUrl:''  
}')
  • 发送
    直接修改地址栏: Url #/myMain/30
    超链接:<a href='#/myStart/30'></a>
    JS实现跳转:$location.path('/myStart/30')
3、动画模块

Angular中实现动画的步骤

  • 引入angular-animate.js
<script src="js/angular-animate.js"></script>
  • 创建模板时指定依赖于ngAnimate
var app=angular.module('myApp',['ng','ngAnimate'])
  • CSS编写

     准备离开:

.page.ng-leave{
    /*准备离开时状态*/
}

    离开完成:

.page.ng-leave.ng-leave-active {
    /*离开完成时状态*/
}

    开始进入:

.page.ng-enter {
     /*开始进入状态*/
}

    进入完成:

.page.ng-enter.ng-enter-active {    
    /*完成进入*/
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值