angular基础( 1.2 -- 2.0版本 )

教程推荐位置:http://www.angularjs.net.cn/tutorial/

本人是比较倾向《angular权威教程》和angular手册结合的方式学习。

调试工具极力推荐:ng-inspector

1、数据绑定

angular数据绑定的两个方式:(1)ng-bind指令(2)差值表达式(3)ng-model双向数据绑定

ng-bind和差值表达式都可以写简单的js表达式,ng-model只能绑定变量名。

ng-bind 和 ng-cloak 可以回避闪烁问题(插值表达式在刚刚加载时显示在页面上)

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>数据绑定</title>
  <script src="angular.js"></script>
</head>
<body>
  <!-- ng-app指定angular作用域  ng-init初始化数据值 -->
  <div ng-app="" ng-init="name='ion';pwd=123456;istrue=true">
    <input type="text" ng-model="name">
    <!-- 注意ng-bind会拿name覆盖掉标签内的所有内容 -->
    <div ng-bind="istrue?name:''">我叫:xxx</div>
    <div>我叫:{{name}}</div>
  </div>
</body>
</html>

<!-- 可以通过控制台-->

2、数据循环

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>数据循环</title>
  <script src="angular.js"></script>
</head>
<body>
  <div ng-app="" ng-init="items=[2,5,3,2];json={'a':1,'b':2,'c':3}">
    <ul>
      <!-- track by 指定唯一key。
        angular出于性能考虑需要数据和视图有一一对应的关系,这里数组出现重复数据不指定唯一key会报错 -->
      <!-- 使用track by 也会导致删除数组一个元素后$index全部发生了改变,视图又要重新渲染 -->
      <li ng-repeat="(index,item) in items track by $index">{{index}}-{{item}}</li>
    </ul>
    <!-- 另一点值得注意的就是当item是数组或者对象时即使内容相同也不需要指定唯一key,因为数组或对象的即使内容相同,当时其都是new Array或者new Object出来的新对象,并不相等,如下代码测试: -->
      <button onclick="check0()">button0</button>
      <button onclick="check1()">button1</button>
      <button onclick="check2()">button2</button>
      <button onclick="check3()">button3</button>

      <ul>
        <!-- 这里不能用$Index,因为这个是下标顺序 -->
        <li ng-repeat="(key,value) in json">{{key}}-{{value}}</li>
      </ul>
  </div>

  <script>
      function check0(){
        alert("1==1:"+(1==1)); //true
      }
      function check1(){
        alert("'a'=='a':"+('a'=='a')); //true
      }
      function check2(){
        alert("[1,2,3]==[1,2,3]:"+([1,2,3]==[1,2,3])); //false
      }

      function check3(){
        alert('{"name":"ion","age":22}=={"name":"ion","age":22}:'+({"name":"ion","age":22}=={"name":"ion","age":22}));  //false
      }
  </script>
</body>
</html>

3、ng环境与js环境

(1)ng环境与js环境不互通

<!DOCTYPE html>
<html lang="en" ng-app="">
<head>
  <meta charset="UTF-8">
  <title>ng环境与js环境不互通</title>
  <script src="angular.js"></script>
</head>
<body ng-init="a=2">
    <input type="text" ng-model="a">
    <input type="button" value="输出" onclick="showmsg()">
    <script>
      function showmsg() {
        console.log(a);  //Uncaught ReferenceError: a is not defined
      }
    </script>
</body>
</html>

(2)ng事件(用法和js相似)

  • ng-click
  • ng-dbl-click
  • ng-mousedown
  • ng-mouseenter
  • ng-mouseleave
  • ng-mousemove
  • ng-keydown
  • ng-keyup
  • ng-keypress
  • ng-change
<!DOCTYPE html>
<html lang="en" ng-app="">
<head>
  <meta charset="UTF-8">
  <title>ng事件</title>
  <script src="angular.js"></script>
</head>
<body ng-init="arr=[{name:'ion'}]">
    <input type="text" ng-model="name">
    //ng事件能操作ng环境的变量
    <input type="button" value="输出" ng-click="arr.unshift({name:name})">
    <ul>
      <li ng-repeat="json in arr">What you input is: {{json.name}}</li>
    </ul>
</body>
</html>

(3)   模块与controller    $scope作用域(打通ng环境与js环境)

<!DOCTYPE html>
<!-- 1.2用模块:将模块名写在ng-app上 -->
<html lang="en" ng-app="test">
<head>
  <meta charset="UTF-8">
  <title>angular模块</title>
  <script src="angular.js"></script>
  <script>
    //1.1声明模块:module的第一个参数是模块名称,第二个参数是该模块依赖于哪些模块,是个数组
    let mod = angular.module('test',[]);
    //2.1写controller,一个模块中可以有多个controller
    mod.controller('ctrl1',function($scope){
      // 这里是ng环境配置方法,方法里面的parseInt是js环境下的函数
      $scope.parseInt = function (str){
        return parseInt(str);
      }

    });
  </script>
</head>
<!-- 2.2用controller -->
<body  ng-controller="ctrl1">
    <input type="text" ng-model="a">
    <input type="text" ng-model="b">
    <!-- 注意parseInt是js环境的函数,angular要调用要加到$scope域下 -->
    {{parseInt(a)+parseInt(b)}}
</body>
</html>

4、内置过滤器和自定义过滤器

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>系统过滤器</title>
</head>
<style>
  div[ng-app] div{background-color: #e91e63;line-height: 2.0;padding: 15px 30px;color: #fff;}
  div[ng-app] div:nth-child(odd){background-color: #795548;}
}
</style>
<body>
      <div  ng-app="myApp" ng-controller="myController">
        <div>
          单价:<input type="number" ng-model="price" />    <br/>
          数量:<input type="number" ng-model="quantity" /> <br/>
          总价:{{(price*quantity) | currency}}
        </div>
        <div>
          筛选数据显示<br/>
          <input type="text" ng-model="search" placeholder="输入筛选条件" />
          <ul>
            <!-- 注意使用时需要加上冒号和筛选值  orderBy也是如此,相当于过滤器参数用冒号添加-->
            <li ng-repeat="item in items | filter:search">
              {{item}}
            </li>
          </ul>
        </div>
        <div>
          自定义过滤器stringMerge<br/>
          <!-- 传参就往后面加“:[参数]”,但是注意第一个参数在管道符|前面 -->
          字符拼接:<em>{{ msg | stringMerge:'are':'god' }}</em>
        </div>
      </div>
      
      <script src="angular.js"></script>
      <script>
        var app = angular.module('myApp', []);
        app.controller('myController', ['$scope','$filter',function($scope,$filter) {
          $scope.price = 9.99;
          $scope.quantity = 2;

          $scope.items=['大黑','小红','大白','小兰'];

          //在JavaScript代码中可以通过$filter来调用过滤器
          $scope.msg=$filter('lowercase')('ION');
          
        }]);
        
        app.filter('stringMerge', function() { //可以注入依赖
            return function(text,text1,text2) {
              return text+" "+text1+" "+text2;
            }
        });
      </script>
</body>
</html>

 自定义过滤器判断字符是否被包含:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="angular.js"></script>
</head>
<body>
    <div ng-app="myApp" ng-controller="myController">
        <div ng-if="surname | isInclude:name">{{'ion' | isInclude:name}}</div>
    </div>
</body>
<script>
    //将控制器写成【name】-Controller 而不是 【name】-Ctrl是一种最佳实践
    angular.module('myApp',[]).controller('myController',function ($scope) {
        $scope.name = 'ion luo';
        $scope.surname = 'luo';
    }).filter('isInclude',function () {
        return function (txt1,txt2) {
            if(txt2.indexOf(txt1)>-1){
                return true;
            }
            else{
                return false;
            }
        }
    });
</script>
</html>

5、内置服务和自定义服务

常见的angular内置服务有:$location、$http、$timeout()和$interval()

可以认为服务就是在angular应用的的一些函数(后两个)或者对象(前两个)。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>内置服务</title>
  <style>
    *{margin:0;padding: 0;}
    body p{background-color: #e91e63;line-height: 2.0;padding: 15px 30px;color: #fff;}
    body p:nth-child(odd){background-color: #795548;}
  </style>
</head>
<body ng-app="myApp" ng-controller="myController">
  <p>
    $location服务用于返回当前页面的URL地址:<br/>
    {{myUrl}}
  </p>
  <p>
    $http 是 AngularJS 应用中最常用的服务。服务向服务器发送请求,应用响应服务器传送过来的数据。<br/>
    服务器返回:{{myDate}}
  </p>
  <p>
    $timeout 服务对应了 JS window.setTimeout 函数。<br/>
    $interval 服务对应了 JS window.setInterval 函数。<br/>
    在angular应用中最好使用angular的服务而不是js的相似功能函数,因为angular服务的支持性更好
    用法一样,我们举一个$timeout服务例子,5s后显示"欢迎您"。
  </p>
</body>
<script src="angular.js"></script>
  <script>
    var app = angular.module('myApp',[]);
    app.controller('myController',['$scope','$location','$http','$timeout',function($scope,$location,$http,$timeout){
      // $location服务用于返回当前页面的URL地址 
      $scope.myUrl = $location.absUrl();

      // $http 是 AngularJS 应用中最常用的服务。服务向服务器发送请求,应用响应服务器传送过来的数据。
      $http.get('welcome.php').then(function(response){
        $scope.myDate = response.date;
      },function(){
        $scope.myDate = "返回数据失败!";
      });

      // $timeout 服务对应了 JS window.setTimeout 函数。
      //$interval 服务对应了 JS window.setInterval 函数。
      $timeout(function(){
        alert("欢迎您!");
      },5000);
    }]);
  </script>
</html>

自定义对象服务

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>自定义服务</title>
  <style>
    *{margin:0;padding: 0;}
    body p{background-color: #e91e63;line-height: 2.0;padding: 15px 30px;color: #fff;}
  </style>
</head>
<body ng-app="myApp" ng-controller="myController">
  <p>
    自定义服务:用于将十进制数字转化成十六进制<br/>
    <!-- 注意这里更改input的值不会更新hex的值 -->
    <input type="number" ng-model="decimalism"><br/>
    {{ decimalism }}的十六进制为:{{ hex }}
  </p>
</body>
<script src="angular.js"></script>
  <script>
    var app = angular.module('myApp',[]);
    //自定义对象服务
    app.service('hexafy',function(){
      this.myFun = function(param){
        return param.toString(16);
      }
    });

    app.controller('myController',function($scope,hexafy){
      $scope.decimalism = 50;
      $scope.hex = hexafy.myFun($scope.decimalism);
    });
  </script>
</html>

6、$http服务

get和post请求的简写格式:

$http.get('/someUrl', config).then(successCallback, errorCallback);
$http.post('/someUrl', data, config).then(successCallback, errorCallback);

7、依赖注入

AngularJS 提供很好的依赖注入机制。以下5个核心组件用来作为依赖注入:

  • (1)value

Value 是一个简单的 javascript 对象,用于向控制器传递值(配置阶段):

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>依赖注入</title>
  <style>
    *{margin:0;padding: 0;}
    body p{background-color: #e91e63;line-height: 2.0;padding: 15px 30px;color: #fff;}
  </style>
</head>
<body ng-app="myApp" ng-controller="myController">
  <p>
    {{ number }}
  </p>
</body>
<script src="angular.js"></script>
<script>
  var app = angular.module('myApp',[]);
  //// 创建 value 对象 "defaultValue" 并传递数据
  app.value('defaultValue',5);
  //将 defaultValue 注入控制器
  app.controller('myController',function($scope,defaultValue){
    $scope.number = defaultValue;
  });   
</script>
</html>
  • (2)service
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>依赖注入</title>
  <style>
    *{margin:0;padding: 0;}
    body p{background-color: #e91e63;line-height: 2.0;padding: 15px 30px;color: #fff;}
  </style>
</head>
<body ng-app="myApp" ng-controller="myController">
  <p>
    {{ number }}
  </p>
</body>
<script src="angular.js"></script>
<script>
  var app = angular.module('myApp',[]);
  //定义服务'calcService',该服务中有个方法square返回一个数字的平方
  app.service('calcService',function(){
    this.square = function(a){
      return a*a;
    }
  });
  //将服务注入控制器
  app.controller('myController',function($scope,calcService){
    $scope.number = calcService.square(5);
  });   
</script>
</html>
  • (3)factory

factory 是一个函数用于返回值。在 service 和 controller 需要时创建。也就是说可以引入到service或者controller。通常我们使用 factory 函数来计算或返回值。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>依赖注入</title>
  <style>
    *{margin:0;padding: 0;}
    body p{background-color: #e91e63;line-height: 2.0;padding: 15px 30px;color: #fff;}
  </style>
</head>
<body ng-app="myApp" ng-controller="myController">
  <p>
    {{ number }}
  </p>
</body>
<script src="angular.js"></script>
<script>
  var app = angular.module('myApp',[]);
  //创建一个 factory 'MathService'用于计算两个数字的乘积
  app.factory('MathService',function(){
    var factory = {};

    factory.multiply = function(a,b){
      return a*b;
    }

    return factory;
  });
  //在service中注入factory,当然controller注入也可以
  app.service('calcService',function(MathService){
    this.multi = function(a,b){
      return MathService.multiply(a,b);
    }
  });
  //再将服务注入控制器
  app.controller('myController',function($scope,calcService){
    $scope.number = calcService.multi(5,6);
  });   
</script>
</html>
  • (4)constant

constant(常量)用来在配置阶段传递数值,注意这个常量在配置阶段是不可用的。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>依赖注入</title>
  <style>
    *{margin:0;padding: 0;}
    body p{background-color: #e91e63;line-height: 2.0;padding: 15px 30px;color: #fff;}
  </style>
</head>
<body ng-app="myApp" ng-controller="myController">
  <p>
    {{ number }}
  </p>
</body>
<script src="angular.js"></script>
<script>
  var app = angular.module('myApp',[]);
  //声明一个常量
  app.constant('constValue','5');
  //将常量注入控制器
  app.controller('myController',function($scope,constValue){
    $scope.number = constValue;
  });   
</script>
</html>
  • (5)provider

AngularJS 中通过 provider 创建一个 service、factory等(配置阶段)。Provider 中提供了一个 factory 方法 get(),它用于返回 value/service/factory。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>依赖注入</title>
  <style>
    *{margin:0;padding: 0;}
    body p{background-color: #e91e63;line-height: 2.0;padding: 15px 30px;color: #fff;}
  </style>
</head>
<body ng-app="myApp" ng-controller="myController">
  <p>
    {{ number }}
  </p>
</body>
<script src="angular.js"></script>
<script>
  var app = angular.module('myApp',[]);
  // 配置service/factory
  app.config(function($provide) {
   $provide.provider('MathService', function() {
      this.$get = function() {
         var factory = {};  
         
         factory.multiply = function(a, b) {
            return a * b; 
         }
         return factory;
      };
    });
  });
  //将MathService注入控制器
  app.controller('myController',function($scope,MathService){
    $scope.number = MathService.multiply(5,6);
  });   
</script>
</html>

8、路由

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>AngularJS 路由实例 - 菜鸟教程</title>
<script src="angular.js"></script>
<script src="https://cdn.bootcss.com/angular.js/1.7.0/angular-route.min.js"></script>
</head>
<body ng-app='routingDemoApp'>
 
    <h2>AngularJS 路由应用</h2>
    <ul>
        <li><a href="#!/">首页</a></li>
        <li><a href="#!/computers">电脑</a></li>
        <li><a href="#!/printers">打印机</a></li>
        <li><a href="#!/blabla">其他</a></li>
    </ul>
     
    <div ng-view></div>
    <script>
        angular.module('routingDemoApp',['ngRoute'])
        .config(function($routeProvider){
            $routeProvider
            .when('/',{template:'这是首页页面'})
            .when('/computers',{template:'这是电脑分类页面'})
            .when('/printers',{template:'这是打印机页面'})
            .otherwise({redirectTo:'/'});
        });
    </script>
</body>
</html>

路由配置时设置对象:

AngularJS 路由也可以通过不同的模板来实现。

$routeProvider.when 函数的第一个参数是 URL 或者 URL 正则规则,第二个参数为路由配置对象。

路由配置对象语法规则如下:

$routeProvider.when(url, {
    template: string,
    templateUrl: string,
    controller: string, function 或 array,
    controllerAs: string,
    redirectTo: string, function,
    resolve: object<key, function>
});

参数说明:

  • template:

    如果我们只需要在 ng-view 中插入简单的 HTML 内容,则使用该参数:

    .when('/computers',{template:'这是电脑分类页面'})
  • templateUrl:

    如果我们只需要在 ng-view 中插入 HTML 模板文件,则使用该参数:

    $routeProvider.when('/computers', {
        templateUrl: 'views/computers.html',
    });

    以上代码会从服务端获取 views/computers.html 文件内容插入到 ng-view 中。

  • controller:

    function、string或数组类型,在当前模板上执行的controller函数,生成新的scope。

  • controllerAs:

    string类型,为controller指定别名。

  • redirectTo:

    重定向的地址。

  • resolve:

    指定当前controller所依赖的其他模块。

9、组件通信

(1)通过公共服务

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body ng-app="myApp">
    <directive1></directive1>
    <directive2></directive2>
</body>
<script src="angular.js"></script>
<script>
    var app = angular.module('myApp',[]);
    //公共对象服务
    app.service('shareService',function () {
        this.names = [];
        this.addName = function(name){
            this.names.push(name);
        }
    });
    //元素指令1,通过公共服务添加输入值到公共服务names数组
    app.directive('directive1',function(shareService){
        return {
            restrict:"E",
            template:"name: <input type='text' ng-model='new_name'/><br/><button ng-click='addName()'>Add</button>",
            link:function (scope,element,attrs) {
                scope.addName = function () {
                    if(scope.new_name){
                        shareService.addName(scope.new_name);
                    }
                }
            }
        }
    });
    //元素指令2,通过公共服务读取通过服务里面的names值
    app.directive('directive2',function (shareService) {
        return {
            restrict:"E",
            template:"<ul><li ng-repeat='list in lists'>{{list}}</li></ul>",
            link:function (scope,element,attrs) {
                scope.lists = shareService.names;
            }
        }
    });
    
</script>
</html>

(2)通过link的attrs实现同一个dom下组件通信

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body ng-app="myApp">
    <directive1 directive2></directive1>
</body>
<script src="angular.js"></script>
<script>
    <!--
    每个directive在定义的时候都有一个link函数,函数签名的第三个参数是attrs,代表在该directive上面的
所有atrributes数组,attrs提供了一些方法,比较有用的是$set和$observe,前者可以自定义attr或修改已经有
的attr的值,后者可以监听到该值的变化。利用这种方式,我们可以让在位于同一个dom元素上的两个directive进
行通讯,因为它们之间共享一个attrs数组。
    -->
    var app = angular.module('myApp',[]);

    app.directive('directive1',function(){
        return {
            restrict:"E",
            template:"<span>{{ time | date:'yyyy-MM-dd HH:mm:ss'}}</span>",
            link:function (scope,element,attrs) {
                attrs.$observe('showValue',function (newValue) {
                    scope.time = newValue;
                });
            }
        }
    });

    app.directive('directive2',function ($interval) {
        return {
            restrict:"A",
            link:function (scope,element,attrs) {
                let defInterval = $interval(function () {
                    attrs.$set("showValue",new Date().getTime());
                },1000);

                scope.$on('$destory',function(){
                    $interval.cancel(defInterval);
                });
            }
        }
    });

</script>
</html>

10、系统指令

全部angular系统指令可见angular参考手册,http://www.runoob.com/angularjs/angularjs-reference.html。下面介绍些常用系统指令:

(1)ng-class 和 ng-style

<!DOCTYPE html>
<html ng-app="">
<head>
<meta charset="utf-8">
<title>常见系统指令</title>
<script src="angular.js"></script>
<style>
    .container{width:100px;height:100px;background-color:yellow}
    .box{display: inline-block; }
</style>
</head>
<!-- 注意ng-style里面的属性两个单词需要连写并且后首字母大写 -->
<body ng-init="a='width:100px;height:100px;background-color:red';
               b={width:'100px',height:'100px',backgroundColor:'blue'};
               c='container box';
               d=['container','box']">

    <div style="{{ a }}"></div>

    <div ng-style="b"></div>

    <div class="{{ c }}"></div>

    <div ng-class="d"></div>

</body>
</html>

效果:

(2)ng-switch

该指令和 ng-if 一样当满足条件才渲染到HTML中。(注意 ng-if 没有 ng-else 指令来做if-else条件结构,需要时使用ng-switch)

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>常见系统指令</title>
<script src="angular.js"></script>
</head>
<body ng-app="">
  <select ng-model="site">
    <option value="taobao">淘宝</option>
    <option value="zhihu">知乎</option>
    <option value="jingdong">京东</option>
  </select>


  <div ng-switch="site">
    <div ng-switch-when="taobao"><h1>淘宝</h1></div>
    <div ng-switch-when="zhihu"><h1>知乎</h1></div>
    <div ng-switch-when="jingdong"><h1>京东</h1></div>
    <div ng-switch-default><h1>请选择 >>>>>></h1>  </div>
  </div>
</body>
</html>

(3) ng-bind-html 和 $sce.trustAsHtml()

<!DOCTYPE html>
<html lang="en" ng-app="myApp">
<head>
  <meta charset="UTF-8">
  <title>ng-bind-html和$sce</title>
  <script src="angular.js"></script>
</head>
<body ng-controller= "myController">
  <div ng-bind-html="a"></div>
</body>
<script>
  var app = angular.module('myApp',[]);
  app.controller('myController',function($scope,$sce){
    $scope.a = $sce.trustAsHtml("欢迎来到<a href='https://blog.csdn.net/ion_L' target='_blank'>ion的博客</a>");
  });
</script>
</html>

 注意,低版本的angluar可以直接绑定HTML代码,但是在anglar1.6.4之后必须加上$sce才可以,否则会出现如下报错。

关于$sce的具体内容见:https://www.cnblogs.com/xing901022/p/5100551.html

11、Angular概念图

猜你喜欢

转载自blog.csdn.net/ion_L/article/details/83246308