AngularJS基础(一)

作者: 灵界小灵 | 来源:发表于2018-07-10 18:42 被阅读0次

    1.简介

    AngularJS 是一个 JavaScript 框架, 它是一个以 JavaScript 编写的库。
    AngularJS 通过指令扩展了HTML,且通过表达式绑定数据到 HTML。
    AngularJS 可以构建一个单一页面应用程序(SPAs:Single Page Applications)。

    在开始学习 AngularJS 之前,您需要具备以下基础知识
    • HTML
    • CSS
    • JavaScript

    2.AngularJS指令

    AngularJS 指令是扩展的 HTML 属性,带有前缀 ng-

    • ng-app 指令初始化一个 AngularJS 应用程序
    • ng-init 指令初始化应用程序数据
    • ng-model 指令把元素值绑定到应用程序

    2.1 ng-model

    • ng-model 数据双向绑定
      以下实例中,两个文本域是通过两个 ng-model 指令同步数据的
    <div ng-app="" ng-init="num=1;price=5">
      <h2>价格计算器</h2>
      数量: <input type="number" ng-model="num">
      价格: <input type="number" ng-model="price">
      <br />
      总价:{{num*price}}
    </div>
    
    价格计算器效果图
    • ng-model 可以为应用数据提供状态值, 验证用户输入 . 根据表单域的状态我们可以添加/移除以下类
      ng-empty :
      ng-not-empty :
      ng-touched : 表示用户是否和控件进行过交互
      ng-untouched : 表示用户是否和控件未进行过交互
      ng-valid : 表单是否通过验证。如果表单当前通过验证,它将为true.
      ng-invalid : 未通过验证的表单.
      ng-valid-[key] : 由setValidity添加的所有验证通过的值 `ng-invalid-[key]` : 由setValidity添加的所有验证失败的值
      ng-dirty : 表示用户是否修改了表单。如果为 ture,表示有修改过;false 表示修没有修改过
      ng-pending : 任何为满足$asyncValidators的情况
      ng-pristine : 控件为初始状态
    <form ng-app="" name="myForm" ng-init="myText='10086@mobie.com'">
      Email:<input type="email" name="myEmail" ng-model="myText" required />
      <span ng-show="myForm.myEmail.$error.email">不是一个合法的邮箱地址</span>
      <p>编辑邮箱地址,注意查看状态的改变。</p>
      <h1>状态</h1>
      <p>Valid: {{myForm.myEmail.$valid}} (如果输入的值是合法的则为 true)。</p>
      <p>Dirty: {{myForm.myEmail.$dirty}} (如果值改变则为 true)。</p>
      <p>Touched: {{myForm.myEmail.$touched}} (如果通过触屏点击则为 true)。</p>
    </form>
    
    ng-model 验证用户输入
    • ng-model基于它们的状态为 HTML 元素提供了 CSS 类.
    <head>
      <style>
        input.ng-valid {
           background-color: red;
        }
        input.ng-invalid {
           background-color: lightblue;
        }
      </style>
    </head>
    <body>
      <form ng-app="" name="myForm">
        输入你的名字:
        <input name="myName" ng-model="myText" required>
      </form>
      <p>编辑文本域,不同状态背景颜色会发生变化。</p>
      <p>文本域添加了 required 属性,该值是必须的,如果为空则是不合法的。</p>
    </body>
    
    ng-mode提供的 CSS 类

    2.2 ng-repeat

    • ng-repeat 指令会重复一个 HTML 元素
    <p>使用 ng-repeat 来循环数组</p>
    <div ng-app="" ng-init="names=[{name:'张三',country:'中国'}, {name:'尼古拉斯·赵四',country:'英国'}, {name:'小犬纯三狼',country:'日本'}]">
      <ul>
        <li ng-repeat="x in names">{{ x.name + ', ' + x.country }}</li>
      </ul>
    </div>
    
    ng-repeat
    • ng-repeat-startng-repeat-end 指令 (在ng-repeat-end后循环结束, 所以 x.country 无值)
    <p>使用 ng-repeat-start 和  ng-repeat-end 来循环数组</p>
    <div ng-app="" ng-init="names=[{name:'张三',country:'中国'}, {name:'尼古拉斯·赵四',country:'英国'}, {name:'小犬纯三狼',country:'日本'}]">
      <ul>
        <li ng-repeat-start="x in names">{{ x.name }}</li>
        <li>来自</li>
        <li>{{ x.country }}</li>
        <br ng-repeat-end>
        <li>{{ x.country }}</li>
      </ul>
    </div>
    
    ng-repeat_start 和 ng-repeat-end

    2.3 .directive

    使用 .directive 函数可以添加自定义的指令, 如下图所示,使用驼峰法来命名一个指令 testDirective , 但在使用它时需要以 - 分割 test-directive
    要调用自定义指令, HTML 元素上需要添加自定义指令名,你可以通过以下方式来调用指令

    • 元素名 <test-directive></test-directive>
    • 属性 <div test-directive></div>
    • 类名 <div class="test-directive"></div>
    • 注释 <❗️-- directive: test-directive -->
    <body ng-app="myApp">
      <test-directive></test-directive>
      <script>
        var app = angular.module("myApp", []);
        app.directive("testDirective", function() {
           return {
             template : "<h1>我的自定义指令!</h1><p>使用元素名调用</p>"
           };
        });
      </script>
    </body>
    
    directive自定义指令

    2.4 restrict

    通过使用 restrict 你可以限制你的指令只能通过特定的方式来调用.
    restrict 值可以是以下几种:

    • E 作为元素名使用
    • A 作为属性使用
    • C 作为类名使用
    • M 作为注释使用
    ps:restrict 默认值为 EA, 即可以通过元素名和属性名来调用指令。
    <body ng-app="myApp">
      <test-directive>01</test-directive>
      <div test-directive>02</div>
      <div class="test-directive">03</div>
      <script>
        var app = angular.module("myApp", []);
        app.directive("testDirective", function() {
           return {
             restrict : "CE",
             template : "<h1>限制指令CE</h1><p>可以使用元素名和类名调用</p>"
           };
        });
      </script>
    </body>
    
    restrict 限制指令CE

    directive使用注释调用时与restrict的结合使用(此时template中只能有一对 HTML 标签, 否则不显示)

    <body ng-app="myApp">
      <!-- directive: test-directive -->
      <script>
        var app = angular.module("myApp", []);
        app.directive("testDirective", function() {
           return {
             restrict : "M",
             replace : true,
             template : "<h1>限制指令M, 自定义指令使用注释调用</h1>"
           };
        });
      </script>
      <p><strong>注意:</strong> 我们需要在该实例添加 <strong>replace</strong> 属性, 否则评论是不可见的。</p>
      <p><strong>注意:</strong> 你必须设置 <b>restrict</b> 的值为 "M" 才能通过注释来调用指令。</p>
    </body>
    
    restrict 限制指令M

    3.Scope(作用域)

    概述

    AngularJS 应用组成如下

    • View(视图), 即 HTML.
    • Model(模型), 当前视图中可用的数据.
    • Controller(控制器), 即 JavaScript 函数,可以添加或修改属性.

    Scope 是模型, 是应用在 HTML (视图) 和 JavaScript (控制器)之间的纽带。
    Scope 是一个 JavaScript 对象, 带有属性和方法, 这些属性和方法可以在视图和控制器中使用。
    Scope 可应用在视图和控制器上。

    3.1 Scope的使用

    当你在 AngularJS 创建控制器时,你可以将 $scope 对象当作一个参数传递.
    当在控制器中添加 $scope 对象时,视图 (HTML) 可以获取了这些属性.
    视图中,你不需要添加 $scope 前缀, 只需要添加属性名即可, 示例如下.

    <div ng-app="myApp" ng-controller="myCtrl">
      <h1>{{myname}}</h1>
    </div>
    <script>
      var app = angular.module('myApp', []);
      app.controller('myCtrl', function($scope) {
          $scope.myname = "希言";
      });
    </script>
    <p>控制器中创建一个属性名 "myname",对应了视图中使用 {{ }} 中的名称。</p>
    
    Scope使用

    进阶用法, 示例如下:

    <div ng-app="myApp" ng-controller="myCtrl">
        <input ng-model="myname">
        <h1>{{greeting}}</h1>
        <button ng-click='sayHello()'>点我</button>   
    </div>
    <script>
    var app = angular.module('myApp', []);
    app.controller('myCtrl', function($scope) {
        $scope.myname = "希言";
        $scope.sayHello = function() {
            $scope.greeting = 'Hello ' + $scope.myname + '!';
        };
    });
    </script>
    <p>当你修改输入框中的值时,会影响到模型(model),当然也会影响到控制器对应的属性值。</p>
    
    Scope进阶使用

    3.2 Scope的作用范围

    在以上两个实例中,只有一个作用域 scope,所以处理起来比较简单,但在大型项目中, HTML DOM 中有多个作用域,这时你就需要知道你使用的 scope 对应的作用域是哪一个.

    1. 所有的应用都有一个根作用域 $rootScope , 它作用在 ng-app 指令包含的所有 HTML 元素中, 是各个 controller 中 scope 的桥梁, 用 $rootscope 定义的值, 可以在各个 controller 中使用.
    2. $rootscope 设置的变量在所有controller里面都是可以直接用 {{$root.变量名}} 来显示的,当然也可以赋值给 $scope .
    3. $rootScope 全局对象的属性可在所有子作用域中访问,子作用域互相无法访问对方的私有变量,这一点与js的函数作用域完全一致.
    4. 不同的控制器域内可以有同名的变量。但除非必要,否则不建议这么做,自己都会乱掉.
    5. 后面控制器中定义的 $rootScope 变量,在它前面的控制器中访问不到.
    <div ng-app="myApp">
    
      <!--myCtrl1-->
      <div ng-controller="myCtrl1">
        <h1>姓氏为 {{surname}} 的员工</h1>
        <ul>
          <li ng-repeat="x in names">{{surname}}{{x}} {{country}}</li>
        </ul>
        <div>-{{country_2}}-</div>
        <div>*{{names_2[1]}}*</div>
      </div>
    
      <!--myCtrl2-->
      <div ng-controller="myCtrl2">
        <div>{{names[1]}}</div>
        <div>{{surname}} {{names_2[1]}} </div>
        <p>子作用域互相无法访问对方的私有变量</p>
      </div>
    
      <!--javascript-->
      <script type="text/javascript">
        var app = angular.module('myApp', []);
          app.controller('myCtrl1', function($scope, $rootScope) {
            $rootScope.surname = "李";
            $scope.names = ["大嘴", "明", "时珍"];
            $scope.country_2 =  $rootScope.country; // 访问不到,未定义
        });
          app.controller('myCtrl2', function($scope, $rootScope) {
            $rootScope.country = "中国";
            $scope.names_2 = ["四", "已疯", "冰冰"];
            $scope.surname_2 = $rootScope.surname;
        });
      </script>
    
    </div>
    
    Scope作用域

    进阶用法

    <div ng-controller="myCtrl" id="001">
      <h1>{{surname}}姓成员:</h1>
      <ul>
    <!-- ng-repeat循环对象不能出现重复项, 所以需要添加 track by $index -->
         <li ng-repeat="x in names track by $index">
           {{surname}}{{x}}
           <button ng-click="delPerson($index)">删除</button>
         </li>
      </ul>
      <p>添加成员:<input type="text" ng-model="name" placeholder="请输入要添加的名字" /></p>
      <button ng-click="addPerson(name)">确认添加</button>
    </div>
    
    <script type="text/javascript">
      var app = angular.module('myApp', []);
      app.controller('myCtrl', function($scope, $rootScope) {
          $scope.name = '';
          $rootScope.surname = "李";
          $scope.names = ["大嘴", "明", "时珍", "已疯", "冰冰"];
          $scope.delPerson = function(index) {
            // 将点击删除的对象从数组中移除,angular会自动更新列表
            $scope.names.splice(index, 1);
          }
          $scope.addPerson = function(name) {
           // 输入的对象添加到数组,angular会自动更新列表 
           $scope.names.push(name);
          }
      });
      // 手动初始化
      // angular.bootstrap(document.getElementById('001'), ['myApp']);
      angular.bootstrap(document, ['myApp']);  // 浏览器加载的每个html都会对应一个document对象, 此对象是所有html中dom元素的根节点, 也属于dom元素.
    </script>       
    

    在传统的angularJS应用中,都是通过 ng-appangular 应用绑定到某个 dom 上,这样做会把js代码入侵到html上,angular 提供了手动启动的API: angular.bootstrap(element, [appName], [config]);

    • element:绑定ng-app的dom元素
    • modules:绑定的模块名字
    • config:附加的配置

    注意: angular.bootstrap 只会绑定第一次加载的对象,后面重复的绑定或者其他对象的绑定,都会在控制台输出错误提示

    Scope进阶

    4.ng-controller(控制器)

    ng-controller 定义了应用程序控制器, 控制器是 JavaScript 对象, 由标准的 JavaScript 对象的构造函数创建. 控制器也可以有方法(变量和函数), 在大型的应用程序中,通常是把控制器存储在外部文件中, 只需要把 <script> 标签中链接外部文件即可.

    在上一部分 Scope 中我们已经多次使用过, 关于 controller 中作用域的问题, 还需要注意情况:

    • 如果局部 $scope$rootScope 都存在,且有相同名字的变量,{{变量名}} 指局部变量而不是全局变量,作用域只有当前 controller;{{$root.变量名}} 是全局变量,在 ng-app=""下任何一个 controller 中都能使用。
    • 如果没有 $scope , 只有 $rootScope ,那么 {{变量名}}{{$root.变量名}} 就没区别了。
    <body ng-app="myApp">
      <div ng-controller="myCtrl1">      
        {{first}}<br>                 
        {{$root.first}}<br>           
        {{second}}<br>                
        {{$root.second}}<br>          
      </div>
    <br>
    <br>
      <div ng-controller="myCtrl2">
        {{first}}<br>                
        {{$root.first}}<br>          
        {{second}}<br>               
        {{$root.second}}            
      </div>
    
    <!-- javascript -->
      <script type="text/javascript">
        var app = angular.module('myApp', []);
        app.controller('myCtrl1', function ($scope,$rootScope) {
               $scope.first = 'ctrl局部first';
               $rootScope.first = '全局first';
        });
        app.controller('myCtrl2', function ($scope,$rootScope) {
               $scope.second = 'ctrl2局部second';
               $rootScope.second = '全局second';
        });
      </script>
    
    </body>
    
    ng-controller

    5 过滤器

    AngularJS 过滤器可用于转换数据, 可以通过一个管道字符 | 和一个 过滤器 添加到表达式中.

    过滤器 描述
    uppercase 格式化字符串为大写
    lowercase 格式化字符串为小写
    currency 格式化数字为货币格式 (默认是$)
    json 可以把一个js对象格式化为json字符串
    date 根据不同的日期格式可以将时间戳格式化为一个日期字符串
    number 可以为一个数字加上千位分割, 比如: 123,456,789。同时接收一个参数, 可以指定float类型保留几位小数.
    limitTo 用来截取数组或字符串,接收一个参数用来指定截取的长度, 如果参数是负值, 则从数组尾部开始截取.
    filter 用来处理一个数组, 可以过滤出含有某个子串的元素,作为一个子数组来返回. 可以是字符串数组, 也可以是对象数组. 如果是对象数组, 可以匹配属性的值. 它接收一个参数, 用来定义子串的匹配规则。
    orderBy 可以将一个数组中的元素进行排序,接收一个参数来指定排序规则,参数可以是一个字符串,表示以该属性名称进行排序。可以是 一个函数,定义排序属性。还可以是一个数组,表示依次按数组中的属性值进行排序(若按第一项比较的值相等,再按第二项比较)
    <div ng-app="myApp" ng-controller="myContrl">
       <p>姓名为 {{ name | uppercase}}</p>
       <p>姓名为 {{ name | lowercase}}</p>
       <p>默认的货币转换 {{99 | currency}}</p>
       <p>自定义货币转换 {{99 | currency:"¥"}}</p>
       <p>货币小数点位数 {{99 | currency:'£':4}}</p>
       <p>时间戳转换 {{times | date:"yyyy-MM-dd HH:mm:ss"}}</p>
       <p>格式化数字: {{times | number:2}}</p>
       <p>截取数组或字符串 {{ personArray | limitTo:-1}} </p>
       <p>匹配属性值中含有a的: {{personArray | filter:'a'}}</p>
       <p>匹配属性值中含有4的: {{personArray | filter:4}}</p>
       <p>参数是对象,匹配name属性中含有i的: {{ personArray | filter:{name : 'i'} }}</p>
       <p>参数是函数,指定返回age小于34的 {{ personArray | filter:ageFunc }}</p>
       数组按age属性值进行排序:
       <div ng-repeat= "per in personArray | orderBy: 'age'">{{per.name}} {{per.age}}</div>
       <p>数组按照函数的返回值进行排序: {{ personArray | orderBy: orderFunc }} </p>
       <p>如果age相同,按照name进行倒序: {{ personArray | orderBy: ['age', '-name'] }} </p>
       <p>自定义过滤器 {{name | aa}} </p>
    </div>
    <script type="text/javascript">
       var app = angular.module("myApp", []);
       app.controller('myContrl', function ($scope, $rootScope) {
          $scope.name = "Jack";
          $scope.times = "1517940306000";
          $scope.personArray = [{name:'Tom', age:23},
                                {name:'Cindy', age:34},
                                {name:'Lucis', age:34},
                                {name:'Kalon', age:56}];
          $scope.ageFunc = function(e) {
             return e.age < 34;
          }
       });
       // 自定义过滤器, aa为自定义过滤名称 ,val为穿参.
       // split("")将val切割成数组, reverse()将数组反转,join("")将数组变成字符串.
       app.filter('aa', function() {
          return function(val) {
             return val.split("").reverse().join("");
          }
       })
    </script>
    
    AngularJS_过滤器

    相关文章

      网友评论

        本文标题:AngularJS基础(一)

        本文链接:https://www.haomeiwen.com/subject/strqpftx.html