ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AngularJS学习笔记

2020-10-08 09:34:34  阅读:272  来源: 互联网

标签:function 笔记 ng 学习 module AngularJS scope Model angular


软件工程

软件设计原则

  • 避免重复原则(DRY-不要重复代码)

    • 编程的最基本原则是避免重复。
    • 在程序代码中总会有很多结构体,如循环、函数、类等等。
    • 一旦你重复某个语句或概念,就会很容易形成一个抽象体
    • 造价公式:单位工资 X 3倍 X 开发人数 X 天数
  • 抽象原则

    • 程序代码中每一个重要的功能,只能出现在源代码的一个位置
  • 简单原则(KISS-代码越简单越好)

    • 简单的代码占用时间少,漏洞少,并且易于修改
  • 避免创建不要的代码(YAGNI-不要写不需要的代码)

    • 除非你需要它,否则别创建新功能
  • 尽可能做可运行的最简单的事

    • 在编程中,一定要保持简单原则
    • 作为一名程序员不断的反思“如何在工作中做到简化呢?”
    • 这将有助于在设计中保持简单的路径。
  • 开闭原则(OCP-对拓展持“开放”态度,对修改持“封闭”态度)

    • 你所编写的软件实体(类、模块、函数等)最好是开放的,这样别人可以拓展开发
    • 对于你的代码,得限定别人不得修改
    • 别人可以基于你的代码进行拓展编写,但却不能修改你的代码
  • 最小惊讶原则

    • 最小惊讶原则通常是在用户界面方面引用,但同样适用于编写的代码
    • 代码应该尽可能减少让读者惊喜
    • 你编写的代码只需按照项目的要求来编写。
    • 其他华丽的功能就不必了,以免弄巧成拙
  • 单一责任原则(SRP)

    • 某个代码的功能,应该保证只有单一的明确的执行任务
  • 高内聚低耦合原则(HCLC)

    • 代码的任何一个部分应该减少对其他区域代码的依赖关系
    • 尽量不要使用共享参数
    • 相似的功能代码应尽量放在一个部分
    • 低耦合往往是完美结构系统和优秀设计的标志
  • 最少知识法则/迪米特法则

    • 让一个对象知道的越少越好
    • 该代码只和与其有直接关系的部分连接

软件设计模式

  • 概念

    • 是前人的优秀的项目经验的总结,在某种特定的场景下的特定的代码设计方法
    • C/C++/Java/PHP/JS的设计模式是通用的
    • 总共有23+种设计模式
  • MVC模式

    • Model
      • Model 模型 Modal 模态框 Module 模块
      • 模型,指业务数据,Web项目中由JS中由变量(数字、字符串、对象、数组等)来担当
    • View
      • 视图,指业务数据在用户面前的呈现,Web项目中由HTML(增强型)来担当
    • Controller
      • 控制器,负责获取、删除、更新模型数据,Web项目中由JS中的function来担当

AngularJS概述

Angular概述

  • 概述
    • AngularJS是一个纯JS框架,基于jQuery对DOM操作做了进一步的封装
    • 使用MVC操作代替所有的DOM操作
    • 用于以数据操作为主的SPA(单页应用)应用

Angular四大特性

  • AngularJS的四大特性:
    • 采用MVC模式,页面中再也无需出现DOM操作
      • Model: 模型,即业务数据,ng中由保存在特定范围内的变量来担当
      • View: 视图,负责数据的呈现,ng中由HTML(增强型)来担当
      • Controller: 控制器,负责操作(CDUD)数据,ng中由模块中的function来担当

双向数据绑定

  • 方向一:把Model数据绑定到View上,此后不论何时只要Model发生了改变,则View中的呈现会立即随之改变!

    • 实现方法:都实现了方向一的绑定
      • {{}}
      • ngBind
      • ngRepeat
      • ngIf
      • ngSrc
  • 方向二:把View(表单控件)中修改绑定到Model上,此后不论任何时候,只要View中的数据一修改,Model中的数据会自动随之修改

    • 实现方法:只有ngModel指令
    • 可以使用$scope.$watch('模型变量名', fn)监视一个模型变量值的改变
    • 单行文本输入域、多行文本输入域、下拉框、单选按钮控件默认会把自己的value属性值绑定到一个Model变量
    • 复选框会把一个true/false值绑定到一个Model变量
    • input
    • textarea
    • select 与value相关
    • input[radio] 与value相关
    • input[checkbox]
// 方向一
angular.module('myModule11', ['ng']).
  controller('c11', function($scope, $interval){
    $scope.age = 10;
    $interval(function(){
      $scope.age++;
    }, 1000);
    $scope.sum = 0;
    $scope.sumer = function(){
      $scope.sum++;
    }
  })
// 轮播
angular.module('M12', ['ng']).
  controller('C12', function($scope, $interval){
    $scope.num = 1;
    $scope.pro = function(){
      $interval.cancel(t);
      $scope.num > 1 ? $scope.num-- : $scope.num = 5;                
    }
    $scope.next = function(){
      $interval.cancel(t);
      $scope.num < 5 ? $scope.num++ : $scope.num = 1;
    }
    let t = $interval(function(){
      $scope.num < 5 ? $scope.num++ : $scope.num = 1;
    }, 1000)
  })
// 进度条
angular.module('M13', ['ng']).
  controller('C13', function($scope, $interval){
    let percentage = 0;
    $scope.myStyle = {width: '0%'};
    let t = $interval(function(){
      percentage += 10;
      $scope.myStyle.width = percentage + "%"
      percentage < 100 ? percentage : $interval.cancel(t);
      // if(percentage>=100){
      //     $interval.cancel(t);
      //     console.log('已完成');
      // }
    }, 50)
  })
<!-- 方向二 -->
<!DOCTYPE html>
<html ng-app="M14">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<section class="container" ng-controller="C14">
    <input ng-model="userName">
    <p ng-bind="userName"></p>
</section>
<script src="js/angular.js"></script>
<script>
angular.module('M14', ['ng']).
    controller('C14', function($scope, $interval){
        // 监视一个Model数据的改变
        $scope.$watch('userName', function(){
            console.log($scope.userName);
        })
    })
</script>
</body>
</html>
<!-- 简易版购物车计算器 -->
<!DOCTYPE html>
<html lang="en" ng-app="M15">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
<section class="container" ng-controller="C15">
    <p>简易版购物车计算器</p>
    <p>单价:<input type='text' ng-model="price"> 数量:<input type='number' ng-model="count"> 小计:<span ng-bind='total'>0</span></p>
</section>
<script src="js/angular.js"></script>
<script>
angular.module('M15', ['ng']).
    controller('C15', function($scope, $interval){
        $scope.$watch('price', function(){
            $scope.total = parseInt($scope.price) * parseInt($scope.count);
        })
        $scope.$watch('count', function(){
            $scope.total = parseInt($scope.price) * parseInt($scope.count);
        })
    })
</script>
</body>
</html>
<!--同意条款 ngIf方式 操作DOM-->
<section class="container" ng-controller="C16">
   <input type="checkbox" ng-model='agree'><span>我同意本站的使用条款</span><br>
   <input class='btn btn-success' type="button" value="提交注册信息" ng-if="agree">
</section>
<script>
angular.module('M16', ['ng']).
    controller('C16', function($scope){
        $scope.agree = true;
    })
</script>
<!--同意条款 ngShow方式 操作display-->
<section class="container" ng-controller="C16">
   <input type="checkbox" ng-model='agree'><span>我同意本站的使用条款</span><br>
   <input class='btn btn-success' type="button" value="提交注册信息" ng-show="agree">
</section>
<script>
angular.module('M16', ['ng']).
    controller('C16', function($scope){
        $scope.agree = true;
    })
</script>
<!--同意条款 disabled方式 -->
<section class="container" ng-controller="C16">
   <input type="checkbox" ng-model='agree'><span>我同意本站的使用条款</span><br>
   <input class='btn btn-success' type="button" value="提交注册信息" ng-disabled="!agree">
</section>
<script>
angular.module('M16', ['ng']).
    controller('C16', function($scope){
        $scope.agree = true;
    })
</script>
<!-- 头像选择 -->
<section class="container" ng-controller="C17">
  <select ng-model="portrait">
    <option value="1.jpg">小萝莉</option>
    <option value="2.jpg">小鲜肉</option>
    <option value="3.jpg">萌大叔</option>
    <option value="4.jpg">胖大婶</option>
  </select>
  <img ng-src="img/{{portrait}}" style="width: 120px;">
  <p ng-bind="portrait"></p>
</section>
<script>
angular.module('M17', ['ng']).
  controller('C17', function($scope, $interval){
    $scope.portrait = '1.jpg';
  })
</script>
<!--全选/取消全选-->
<section class="container" ng-controller="C18">
  <table class='table table-bordered'>
    <thead>
      <tr>
        <th>选择</th>
        <th>姓名</th>
        <th>工资</th>
        <th>操作</th>
      </tr>
    </thead>
      <tbody>
        <tr ng-repeat="item in employee">
          <td><input type='checkbox' ng-checked="selectAll"></td>
          <td ng-bind="item.name">Sunny</td>
          <td ng-bind="item.salary">8500</td>
          <td><button class='btn btn-danger'>删除</button></td>
        </tr>
      </tbody>
  </table>
  <input type="checkbox" ng-model="selectAll">
  <span ng-hide='selectAll'>全选</span>
  <span ng-show='selectAll'>取消全选</span>
</section>
<script src="js/jquery-1.11.3.js"></script>
<script src="js/angular.js"></script>
<script>
angular.module('M18', ['ng']).
  controller('C18', function($scope){
    $scope.employee = [{
      name: 'Sunny',
      salary: 7200
    },{
      name: 'Tom',
      salary: 6400
    },{
      name: 'Jerry',
      salary: 7800
    }]
    $scope.selectAll = false;
  })
</script>

依赖注入

  • 依赖注入概念
    • 依赖(Dependency):Driver对象的创建和运行必须一个car对象,称为Drive对象,“依赖于”Car对象
function(car){
  car.start();
  car.run();
  car.stop();
}
  • 依赖对象的解决方法:
    • 主动创建
    • 被动注入(inject)
      • 一般由特定框架来创建Driver对象,发现其依赖于一个Car对象,框架自动创建被依赖的Car对象 —— 称为“依赖注入”
// 主动创建
var c1 = new Car();  // 创建被依赖的对象
var d1 = new Driver(c1); // 使用被依赖的对象
// 依赖注入
module.controller('控制器名', function(){$scope, $http})
  • 控制器的创建

    • 控制器对象不能受手动创建
    • 必须由框架来创建
      • <div ng-controller="C30"></div>
    • 注意:
      • 控制器对象的构造函数是由AngularJS来调用的,不能手动调用
      • Angular会根据控制器对象的构造函数的形参名来创建依赖的参数对象(形参名不能随意指定!)
      • 若控制器对象未声明形参,则Angular不会传递任何实参进来
      • 控制器对象的形参名必须是Angular可识别的,但是数量和顺序没有限制
      • AngularJS会根据每一个形参的名称来查找创建被依赖的对象,并自动注入进来
  • JS压缩功能的解决方案

    • 若使用了JS的压缩功能,会自动将依赖对象的形参进行精简混淆,则Angular就无法再根据形参名实现依赖注入了
    • 在数组内,形参的数量与顺序一一对应
angular.module('M30', ['ng']).
    controller('C30', ['$scope', '$http', '$animate' ,function(a, b, c){
        console.log('c3控制器对象的实例开始创建...');
        console.log(arguments);
        console.log('c3控制器对象的实例创建完成!');
    }])

模块化(Module)设计

  • 设计原则

    • 模块化设计体现着“高内聚低耦合”设计原则
    • 项目中,可以根据功能的不同,将不同的组件放置在不同的模块中
      • 用户管理相关内容全部放在userModule
      • 商品相关的内容全部放在productModule
  • AngularJS中有两种模块

    • AngularJS官方提供的模块
      • ng ngRoute ngAnimate ngTouch ...
    • 用户自定义的模块
      • userModule productModule orderModule ...
    • 一个AngularJS的模块中可以包含哪些组件?
      • controller组件:用于维护Model模型数据(自定义模块)
      • directive组件:用于View中输出/绑定Model数据
      • service组件:用于在不同的控制器中提供某种函数服务
      • filter组件:用于对View中输出的数据进行格式化
      • provider组件:
      • function组件:
      • object组件:
      • type组件:
  • Angular模块中的常用组件之filter

    • filter:过滤器,用于Model数据在View中呈现时进行某种格式的筛选/过滤/格式化
    • 在View中使用过滤器时,需要借助于管道 |
    • ng模块中提供的过滤器
      • lowercase 把数据格式化为小写
        • 语法:{{表达式 | lowercase}}
      • uppercase 把数据格式化为大写
        • 语法:{{表达式 | uppercase}}
      • number 把数字型数据格式化为三位一个逗号的字符串,同时指定小数点位数
        • 语法:{{表达式 | number:小数位数}}
      • currency 把数字型数据格式化为货币格式的字符串,同时指定货币符号
        • 语法:{{表达式 | currency:'货币符号'}}
      • date 把数据/Date型数据格式化为特定日期时间格式的字符串
        • 真实项目中,往往不使用Date类型表示日期时间
        • 而使用长整型的数字来代替
        • 所有的编程语言/数据库系统都支持长整型数字,都可以把数字和日期时间随意的转换
        • 语法: {{表达式 | date:'日期时间格式'}}
<section class="container" ng-controller="C31">
    <p ng-bind="ename"></p>
    <p ng-bind="ename.toUpperCase()"></p>
    <!--过滤器在使用时要借助管道-->
    <p ng-bind="ename | uppercase"></p>
    <p ng-bind="ename | lowercase | uppercase"></p>
</section>
<script>
angular.module('M31', ['ng']).
    controller('C31', function($scope){
        $scope.ename = 'Tom';
    })
</script>
<!--服务器中运行-->
<!DOCTYPE html>
<html lang="en" ng-app="M32">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
<!--
    点击一个按钮“加载员工数据”,
    向服务器发起异步的AJAX请求,
    获取服务器的一段JSON数据;
    加载完数据后,按钮即禁用/消失
-->
<section class="container" ng-controller="C32">
  <button class='btn btn-success' ng-click='loadData()' ng-disabled='agree'>加载员工数据...</button>
  <hr>
  <table class="table">
    <thead>
      <tr>
        <th>序号</th>
        <th>姓名</th>
        <th>工资</th>
        <th>入职日期</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat='(key, item) in employee'>
        <td ng-bind='key'></td>
        <td ng-bind='item.ename | uppercase'></td>
        <td ng-bind='item.salary | currency:"¥ "'></td>
        <td ng-bind='item.hiredate | date:"yyyy年mm月dd日"'></td>
      </tr>
    </tbody>
  </table>  
</section>
<script src="js/jquery-1.11.3.js"></script>
<script src="js/angular.js"></script>
<script>
angular.module('M32', ['ng']).
  controller('C32', function($scope, $http){
    $scope.loadData = function(){
      $scope.agree = true;
      $http.get('data/5.json').success(function(data){
        $scope.employee = data;
      })
    }
  })
</script>
</body>
</html>
// 5.json
[{
    "ename": "Tom",
    "salary": 12000,
    "hiredate": 1601968856625
},{
    "ename": "Jerry",
    "salary": 15000,
    "hiredate": 1604588394625
},{
    "ename": "John",
    "salary": 9000,
    "hiredate": 1601969624625
},{
    "ename": "Sunny",
    "salary": 13000,
    "hiredate": 1601884394625
},{
    "ename": "Mary",
    "salary": 11000,
    "hiredate": 1601968394815
}

AngularJS数据绑定的原理&最大的缺陷

  • 绑定原理

    • 每一次方向1的绑定都会在$digest队列中生成一个执行DOM操作的函数
    • 若一个ngApp中有N次数据绑定就会生成N个这样的函数
    • 只要某一个Model数据发生了值的改变,立即会自动执行$digest队列的每一个函数,进行View的更新
    • 队列的数据轮询
  • setInterval()和$interval()的不同

    • window.setInterval()只会执行指定的任务,即使修改了Model数据也不会自动轮询$digest队列
    • $interval()的执行体中会在最后自动执行:$scope.$digest()/$scope.$apply()
      • 轮询$digest队列,执行其中的每一个DOM操作函数
      • 简言之,$interval = setInterval()+$scope().$digest()
<!DOCTYPE html>
<html lang="en" ng-app="M20">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
<section class="container" ng-controller="C20">
    <p>完整版购物车计算器</p>
    <button class='btn btn-success' ng-click='addProduct()'>添加商品</button>
    <hr/>
    <div>
        <p ng-repeat="(index, item) in cart" class='alert alert-success'>
            单价:<span ng-bind='item.price'></span>
            数量:<input type='number' ng-model="item.count">
            小计:<span ng-bind='item.price*item.count'>0</span>
        </p>
    </div>
    <div>总计:<span ng-bind='getTotal()'></span></div>
</section>
<script src="js/jquery-1.11.3.js"></script>
<script src="js/angular.js"></script>
<script>
    angular.module('M20', ['ng']).
        controller('C20', function($scope, $interval){   
            $scope.cart = []
            $scope.cart.push({price: 10.5, count: 2});
            $scope.cart.push({price: 5.5, count: 5});
            $scope.addProduct = function(){
                let p = {price: Math.round(Math.random()*500)/10, count: Math.ceil(Math.random()*10)}
                $scope.cart.push(p);
                console.log($scope.cart.count);
            }
            $scope.getTotal = function(){
                let total = 0;
                angular.forEach($scope.cart, function(v, k){
                    total += v.count * v.price; 
                    console.log(v);
                })
                return total
            }
        })
    </script>
</body>
</html>

Angular国际化项目

  • 国际化项目
    • internationalization
    • 简写 i18n
    • 一个项目可以根据客户端的不同,呈现出不同的语言

Angular表达式

  • Angular表达式
    • 语法:{{表达式}}
    • 作用:在当前位置“输出”该表达式的值
    • 表达式运算
      • 算术运算 自加自减不可以
      • 比较运算 都可以
      • 逻辑运算 都可以
      • 三目运算 都可以
      • 赋值运算 += -= *= 等运算赋值不可以
      • 特殊运算符 不可以使用typeof()
      • 调用string的方法和属性
        • {{"apple".split('')}} 字符串变数组
        • {{"apple".slice(1, 4)}} 提取字符串
        • {{"apple".substr(0, 4)}} 从字符串某处提取N个字符
        • length属性 <span ng-init="ename='Tom'"></span> <p>{{ ename.length }}</p>
        • toUpperCase()方法 <span ng-init="ename='Tom'"></span> <p>{{ ename.toUpperCase() }}</p>
      • 创建新对象
        • 直接量语法: <p>{{ {ename:'Tom',age:30}.age }}</p>
        • new 构造方法:不可以
      • 创建数组
        • 数组直接量:<p>{{ [1,2,3] }}</p>
        • 数组直接量:<p>{{ [1,2,3][1] }}</p>
        • new Array:不可以

Angular模块指令

  • Angular中ng模块提供的指令(Directive)
    • ngAPP: 自动载入/启动一个Angular应用
      • 语法:
        • ng-app
        • <ANY ng-app="xxx"></ANY>
        • <ANY ng-app></ANY>
        • <ANY data-ng-app="xxx"></ANY>
      • 注意:一个HTML页面中只允许使用一次ngApp指令!用于确定AngularJS应用的范围
    • ngInit: 用于声明Model变量
      • ng-init
      • 语法:<ANY ng-init="变量名=值;变量名=值;..."></ANY>
      • 注意:Model变量声明时不能使用Var
    • ngController: 创建一个控制器对象的实例(即调用Controller函数)
      • ng-controller
      • 语法:<ANY ng-controller="控制器名"></ANY>
    • ngBind: 在当前元素的innerHTML上输出指定的表达式的值
      • ng-bind
      • 语法:<ANY ng-bind="表达式"></ANY>
      • 说明:此指令的作用与{{}}一样,只是可以防止闪动问题
    • ngRepeat: 为HTML增加循环功能,循环输出当前元素
      • 语法:<ANY ng-repeat="变量名 in Model数组/对象"></ANY>
      • 语法:<ANY ng-repeat="(下标, 值) in Model数组/对象"></ANY>
    • ngIf: 为HTML增加选择功能,
      • 只有在表达式值为true时,当前元素才添加到DOM树
      • 否则就从DOM树上删除
      • 语法:<ANY ng-if="表达式"></ANY>
    • ngSrc: 解决img等标签的src属性中包含{{}}产生的404问题
      • 语法:<img ng-src="路径/{{表达式}}">
    • ngClick: 为元素绑定监听函数(不是全局函数,而是Model函数)
      • 语法:<ANY ng-click="模型函数()"></ANY>
      • 注意:使用$scope.模型函数名 = function(){}格式来声明模型函数
    • ngStyle: 允许你在HTML元素上条件化设置CSS样式
      • 语法:<ANY ng-style="属性对象"></ANY>
      • 赋值为一个Model对象,用于为当前元素指定样式
    • ngModel: 使用NgModelController绑定一个 input,select, textarea (或自定义表单控件) 到域上的一个属性
      • 语法:
    • ngShow: 根据ngShow属性上表达式来显示或隐藏给定的HTML元素,通过display:none/block来控制当前元素是否显示
      • 语法:<ANY ng-show="表达式"></ANY>
    • ngHide: 根据ngHide属性上表达式来显示或隐藏给定的HTML元素,通过display:none/block来控制当前元素是否显示
      • 语法:<ANY ng-hide="表达式"></ANY>
    • ngDisabled: 赋值为true/false,可以控制当前元素是否禁用
      • 语法:<ANY ng-disabled="表达式"></ANY>
    • ngChecked: 赋值为true/false,可以控制当前元素是否选中
      • 语法:<ANY ng-checked="表达式"></ANY>
<!-- ngInit指令 -->
<div class="container" >
    <h2>Angular中创建Model变量的两种方法</h2>
    <h3>使用ngInit指令</h3>
    <!-- ngInit指令作为HTML元素属性来使用 -->
    <span ng-init="price=10.5"></span>
    <p>{{ price }}</p>
    <!-- ngInit指令作为HTML元素样式来使用 -->
    <span class="ng-init: price=22.5"></span>
    <p>{{ price }}</p>
</div>
  • Angular中ngAnimate模块提供的指令

  • Angular中ngRoute模块

    • 概念:
      • ngRoute模块可以让用户自定义“路由字典”
      • 自动解析请求URL中的理由地址,查找路由字典
      • 自动发起异步AJAX请求,把获取的结果放在当前页面中
    • 使用ngRoute模块的步骤:
      • 创建唯一完整的页面:index.html,引入angular.js和angular-route.js
      • 在index.html的body中使用ngView指令声明一个容器元素用于盛放模板页面
      • 创建自定义模块,声明依赖于ng和ngRoute两个模块
      • 在当前模块中使用ngRoute提供的对象配置路由字典
        • 调用config(function(){})
        • 注入方法 $routeProvider
      • 再创建几个模板页面,只需要有div元素即可
      • 测试路由字典的配置是否正确
<!--index.html-->
<!DOCTYPE html>
<html ng-app="M33">
<head lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>   
<div ng-view></div>
<script src="js/jquery-1.11.3.js"></script>
<script src="js/angular.js"></script>
<script src="js/angular-route.js"></script>
<script>
angular.module('M33', ['ng', 'ngRoute']).
  config(function($routeProvider){
    $routeProvider.
      when('/start', {
        templateUrl: 'tpl/start.html'
      }).
      when('/main', {
        templateUrl: 'tpl/main.html'
      }).
      when('/detail', {
        templateUrl: 'tpl/detail.html'
      }).
      otherwise({
        // 若URL中未提供路由地址或提供了不存在的路由地址
        // 重定向
        redirectTo: '/start'
      })
  })
</script>
</body>
</html>
<!--start.html-->
<div class="panel panel-danger">
    <div class="panel-heading">
        <h3 class="panel-title">
            Start
        </h3>
    </div>
    <div class="panel-body">
        起始页
        <p><a href="#/detail" class='btn btn-success'>跳转到详情页</a></p>
        <p><a href="#/main" class='btn btn-success'>跳转到菜单页</a></p>
    </div>
</div>
<!--detail.html-->
<div class="panel panel-success">
    <div class="panel-heading">
        <h3 class="panel-title">
            Start
        </h3>
    </div>
    <div class="panel-body">
        详情页
        <p><a href="#/start" class='btn btn-success'>跳转到起始页</a></p>
        <p><a href="#/main" class='btn btn-success'>跳转到菜单页</a></p>
    </div>
</div>
<!--main.html-->
<div class="panel panel-info">
    <div class="panel-heading">
        <h3 class="panel-title">
            Start
        </h3>
    </div>
    <div class="panel-body">
        菜单页
        <p><a href="#/detail" class='btn btn-success'>跳转到详情页</a></p>
        <p><a href="#/start" class='btn btn-success'>跳转到起始页</a></p>
    </div>
</div>

Angular业务数据

  • Angular中声明变量——Model数据
    • 有两种方式可以声明Model变量
      • 使用ngInit指令声明
        • ngInit指令可以声明为HTML元素的属性或样式
        • ngInit指令声明的Model变量可以先使用再声明
        • ngInit指令可以一次声明多个Model变量,用分号隔开即可
        • ngInit指令可以声明哪些类型的Model变量
          • number 可以
          • string 可以
          • boolean 可以
          • 对象 直接量可以
          • 数组 直接量可以
          • 对象的数组 直接量可以
          • 注意:使用ng-init定义Model变量时,不能使用new关键字
          • 此方法把View和Model混杂在一起,不推荐使用
      • 使用Controller创建Model变量 推荐使用
        • 创建模块 <= 创建Controller <= 创建Model变量
        • 注意:新版本的Angular要求控制器必须声明在一个模块中!
        • 具体步骤
          • 声明一个自定义的模块(module)
            • angular.module('模块名',[])
          • 在当前AngularJS应用中注册自定义模块
            • ng-app="模块名"
          • 在自定义模块中创建Controll函数,其中创建Model数据
            • $scope是AngularJS中的域模型,也称为作用域实例,其实就是个可劲儿造的空对象
            • $scope.模型变量名 = 值;
          • 在View中创建Controller对象的实例,指定其作用范围
            • <ANY ng-controller="控制器名">...控制器的有效范围...</ANY>
          • 在控制器的作用范围内输出控制器中声明的Model变量
            • 可以使用{{}}输出Model变量的值
<!-- MVC基础操作 -->
<!DOCTYPE html>
<!-- 2.在Angular应用中注册自定义模块 -->
<html ng-app="myModule1">
<head lang="en">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
  <div class="container">
    <div ng-controller="myController1">
      <!-- 5.在控制器的作用范围内输出控制器中声明的Model变量 -->
      <p>ename:{{ename}}</p>
      <p>age:{{age}}</p>
      <p>birthday:{{birthday.getFullYear()+'-'+(birthday.getMonth()+1)}}</p>
    </div>
    <div ng-controller="myController2">
      <p>ename:{{ename}}</p>
      <p>age:{{age}}</p>
      <p>birthday:{{birthday.getFullYear()+'-'+(birthday.getMonth()+1)}}</p>
    </div>
  </div>
<script src="js/angular.js"></script>   
<script>
  // 1.声明自定义模块
  angular.module('myModule1', ['ng']).
    controller('myController1', function($scope){
      // 3.创建一个Controller函数
      console.log('1对象的实例开始创建...');
      // 4.使用Controller函数创建/修改/删除Model数据
      $scope.ename = 'Tom';
      $scope.age = 18;
      $scope.birthday = new Date();
      console.log('1对象的实例创建完成!');
    }).
    controller('myController2', function($scope){
      // 3.创建一个Controller函数
      console.log('2对象的实例开始创建...');
      // 4.使用Controller函数创建/修改/删除Model数据
      $scope.ename = 'Jerry';
      $scope.age = 19;
      $scope.birthday = new Date();
      console.log('2对象的实例创建完成!');
    })
</script>
</body>
</html>
<!-- 对象操作 -->
<!DOCTYPE html>
<html ng-app="myMd5">
<head lang="en">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
<div class="container">
  <div ng-controller="myCtrl5">
    <p>name:{{stu.sname}}</p>
    <p>age:{{stu.age}}</p>
    <p ng-bind="'生日:'+stu.birthday.getFullYear()"></p>
    <p ng-bind="'性别:'+stu.sex"></p>
    <p>成绩:{{stu['score']}}</p>
  </div>
</div>
<script src="js/angular.js"></script>   
<script>
  angular.module('myMd5', ["ng"]).
    controller("myCtrl5", function($scope){
      $scope.stu = new Object;
      $scope.stu.sname = 'Sunny';
      $scope.stu.age = 23;
      $scope.stu.sex = "女";
      $scope.stu.score = 99;
      $scope.stu.birthday = new Date();
    })
</script>
</body>
</html>
<!-- for循环 -->
<!DOCTYPE html>
<html ng-app="myMd6">
<head lang="en">
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
<div class="container">
  <div ng-controller="myCtrl6">
    <p>{{scoreList}}</p> 
    <ul>
      <li ng-repeat="item in scoreList">
        {{item}}
      </li>
      <li ng-repeat="(index, num) in scoreList">
        {{index}} - {{num}}
      </li>
    </ul>
  </div>
</div>
<script src="js/angular.js"></script> 
<script>
  angular.module("myMd6", ["ng"]).
    controller("myCtrl6", function($scope){
      $scope.scoreList = [95, 93, 89];
      $scope.scoreList.push(99);
      $scope.scoreList[$scope.scoreList.length] = 94;
    })
</script>
</body>
</html>

Angular域模型 (实例作用域)

  • $scope $rootScope

    • 每个控制器的实例都对应一个作用范围对象,即$scope
    • 在控制器中声明的Model数据,必须保存在控制的作用范围内
    • 一个HTML中可以声明多个控制器实例,每个控制器都有自己的作用范围,这些范围内的数据彼此隔离,不会相互影响,可以由不同的开发人员来编写
    • 为了在多个控制器间共享数据,可以将Model数据保存在一个"全局作用范围内"
    • $rootScope 真个AngularAPP中有且只有一个$rootScope对象
    • 且此对象是所有$scope的父作用域对象
  • 作用域对象的关系

    • 嵌套关系的作用域

ng模块中提供的服务(server)

  • $rootScope

    • 用于在不同的控制器间共享数据
  • $interval

    • 提供周期性定时器服务
angular.module('myModule11', ['ng']).
  controller('c11', function($scope, $interval){
    $scope.age = 10;
    let t = $interval(function(){
      $scope.age > 100 ? $interval.cancel(t) : $scope.age++;
    }, 1000)
  })
  • $timeout

    • 提供一次性定时器服务
  • $http

    • 发起异步的AJAX请求服务
<?php
// 向客户端输出员工的信息,以JSON格式
header('Content-Type: application/json');
$empList = [];
$empList[] = [
    'eno' => 101,
    'ename' => 'Tom',
    'salary' => rand(1000, 10000)
];
$empList[] = [
    'eno' => 102,
    'ename' => 'Jerry',
    'salary' => rand(4500, 10000)
];
$empList[] = [
    'eno' => 103,
    'ename' => 'Sunny',
    'salary' => rand(1000, 10000)
];
$str = json_encode($empList);
echo $str;
?>
<!DOCTYPE html>
<html lang="en" ng-app="M19">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <link rel="stylesheet" href="css/bootstrap.css">
</head>
<body>
<section class="container" ng-controller="C19">
  <button class='btn btn-success' ng-click='loadEmpInfo()'>加载员工数据...</button>
  <table class='table table-bordered'>
    <thead>
      <tr>
        <th>选择</th>
        <th>姓名</th>
        <th>工资</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      <tr ng-repeat="item in employee">
        <td><input type='checkbox' ng-checked="selectAll"></td>
        <td ng-bind="item.eno">Sunny</td>
        <td ng-bind="item.ename">Sunny</td>
        <td ng-bind="item.salary">8500</td>
        <td><button class='btn btn-danger'>删除</button></td>
      </tr>
    </tbody>
  </table>
  <input type="checkbox" ng-model="selectAll">
  <span ng-hide='selectAll'>全选</span>
  <span ng-show='selectAll'>取消全选</span>
</section>
<script src="js/jquery-1.11.3.js"></script>
<script src="js/angular.js"></script>
<script>
angular.module('M19', ['ng']).
  controller('C19', function($scope, $http){
    $scope.employee = [];
    $scope.selectAll = false;
    $scope.loadEmpInfo = function(){
      // 点击按钮,则向服务器发起AJAX请求
      $http.get('data/19.php').
        success(function(data){
            for(let i=0; i<data.length;i++){
              $scope.employee.push(data[i]);
            }
        })
    }
  })
</script>
</body>
</html>

如何压缩css/js文件,得到xx.min.js/css

  • YUI框架:Yahoo User Interface,是由雅虎的前端工程师将自己的工作经验整理出来的工具集合,其中一个小工具:

    • yui-compressor,可用于压缩CSS和JS文件
    • yuicompressor-2.4.2.jar 置放于C盘根目录下
    • 使用步骤:
      • 下载并安装Java语言的运行环境——JDK
      • 在Java命令下运行yui-compressor工具
        • java.exe -jar c:/yui-comressor-2.4.2.jar e:/my.js >e:/my.min.js
        • 也可以把此工具配置为WebStorm中的FileWatcher(files/setting/tools),只要用户编辑一个.js/.css文件,即自动调用此工具得到压缩后的文件
    • 压缩效果:
      • 删除所有的注释
      • 删除没有语义的空白字符
      • 尽可能简化局部的变量名,函数名,形参名 —— 称为混淆
      • 注意:所有的数据值(如数字、字符串等)、关键字不会做任何改变
      • ctrl+alt+L 压缩恢复
  • JS框架

// 自调函数的写法
/*
*这是我的一个JS框架
* author: 文华
* email:  liwenhua@tedu.cn
* */
+function(win, doc){
  var age = 20;
  var ename = 'Tom Cruise';

  //下面有一个执行相加操作的函数
  function add(num1, num2){
    var sum  = 0;
    sum = num1 + num2;
    return sum;
  }

  add(age, ename);   //调用add函数

}(window, document);

Web项目中“单页应用”和“多页应用”的比较

  • 多页应用

    • 一个项目中有多个完整的.html页面
    • 多个页面间的跳转可以使用超链接、表单提交、JS(location.href="xx.html")
    • 页面切换是同步请求:客户端先删除第一个页面的DOM结构,发起HTTP请求,等待服务器给第二个页面的响应数据...一片惨白
    • 每个页面都是一个完整的DOM树
    • 页面切换时控制权在浏览器手中,不可能添加任何的过场动画效果
  • 单页应用(SPA)

    • 只有一个.html是完整的(缺少body主体),其他.html都是不完整的(可能只是一个div而已)
    • 多个“伪页面”间的跳转可以使用超链接、JS(...)
    • 伪页面切换是异步请求:客户端首先请求一个完整的页面,然后再发起异步AJAX请求,获取不同的模板页面,插入在当前的DOM树
    • 整个项目只有一个完整的DOM树
    • 伪页面切换的本质是一棵DOM树上的两个DIV在切换,可以很容易的添加各种过场动画
  • 总结

    • 单页应用完全可以实现传统的多页面的效果
    • 同时还可以降低服务器和客户端数据传输量、加快页面显示速度、添加丰富的过场动画效果!

如何仿照AngularJS实现SPA的页面切换效果

  • 页面URL形如:
    • http://127.0.0.1/index.html#/路由地址
    • 浏览器首先请求基础页面(index.html),再解析URL中的路由地址
    • 查找路由字典,形如
      • /start -> tpl/start.html

      • /main -> tpl/main.html

      • ...
      • 获取当前URL中路由地址所对应的真实模板页面的地址
      • location.protocol
      • location.hostname
      • location.port
      • location.path
      • location.hash
    • 客户端发起异步AJAX请求,获取目标模板页面,将服务器返回的HTML片段(只含有几个DIV),插入到当前的DOM树上

标签:function,笔记,ng,学习,module,AngularJS,scope,Model,angular
来源: https://www.cnblogs.com/SharkJiao/p/13780314.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有