AngularJS 基础

AngularJS基础(一)

2018-07-10  本文已影响0人  灵界小灵

1.简介

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

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

2.AngularJS指令

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

2.1 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>
价格计算器效果图
<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 验证用户输入
<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

<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
<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 元素上需要添加自定义指令名,你可以通过以下方式来调用指令

<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 值可以是以下几种:

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 应用组成如下

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]);

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

Scope进阶

4.ng-controller(控制器)

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

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

<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_过滤器
上一篇下一篇

猜你喜欢

热点阅读