《AngularJs实战》学习笔记(慕课网)

1. Controller使用过程中的注意点

  1. 不要试图去复用Controller, 一个控制器一般只负责一小块视图
  2. 不要在Controller中操作DOM, 这不是控制器的职责. 封装在指令里. 
  3. 不要在Controller中做数据格式化, ng有很好用的表单控件
  4. 不要在Controller里面做数据过滤操作, ng有$filter服务
  5. 一般来说, Controller是不会互相调用的, 控制器之间的交互会通过事件进行  ---> 这是强耦合

2. 

<html ng-app>   <!--这里ng-app告诉浏览器,这里的html元素是AngularJS应用程序的“所有者”-->
    <div>
        <input ng-model="greeting.text"/>   <!--ng-model把输入域的值绑定到应用程序变量greeting.text-->
        <p>{{greeting.text}}, Angular</p>   <!-- 双大括号{{}}是AngularJS表达式:把数据绑定到HTML,与ng-bind指令异曲同工。-->
                          <!-- AngularJS将在表达式书写的位置“输出”数据-->

                          <!--它很像JS表达式,可以包含文字,运算符和变量-->

</div> .... <script src="js/angular-1.3.0.js"></script> <html>

则p标签中的值会随着input里的输入进行改变. 

启动后, 会找ng-app中的指令. 找到ng-model后会生成greeting.text数据模型, 这个模型挂载scope根目录下, 这样所有的{{greeting.text}}都可以获得其值

 

3. AngularJS四大核心特性

  • MVC
  • 模块化和依赖注入
  • 双向数据绑定
  • 指令

 

 

4. 关于$scope

  1. Angularjs的MVC是借助于$scope实现的:
    1.  作用域也是有层次结构的, 如果在内层作用域中没有找到值则会向上去找, 类似JS中的原型查找
  2. $scope是一个POJO(Plain Old JavaScript Object)
  3. $scope提供了一些工具方法$watch()/$apply()
  4. $scope是表达式的执行环境(或者叫作用域)
  5. $scope是一个树形结构, 与DOM标签平行
  6. 子$scope对象会继承父$scope上的属性和方法
  7. 每一个Angular应用只有一个根$scope对象(一般位于ng-app上)
  8. $scope可以传播事件, 类似DOM事件, 可以向下也可以向上
  9. $scope不仅是MVC的基础, 也是后面实现双向数据绑定的基础
  10. 可以用angular.element($0).scope()进行调试
  11. $scope的生命周期: Creation->Watcher registration->Model mutation->Mutation observation->Scope destruction

 5. AngularJS模块化

var helloModule=angular.module('HelloAngular',[]);
helloModule.controller('helloNgCtrl', ['$scope', function($scope){
    $scope.greeting = {
        text: 'Hello'
    };
}]);

一个完整项目结构

[目录]BookStore
|    [目录]app
|      |  [目录]css
|      |  [目录]framework
|      |  [目录]imgs
|      |  [目录]js.............................存放js文件
|      |    |  app.js.........................作为启动点的js
|      |    |  controllers.js
|      |    |  directives.js
|      |    |  filters.js
|      |    |- services.js
|      |  [目录]tpls...........................放一些模板,即不完整的html文件片段
|      |    |  bookList.html
|      |    |- hello.html
|      |- index.html..........................应用的html文件
|    [目录]node_modules.......................各种基于NodeJS的工具
|      |  [目录]http-server
|-     |- package.json........................npm配置项
  1. ng-app:定义应用程序的根元素
  2. ng-bind:绑定HTML元素到应用程序数据
  3. ng-bind-html:绑定HTML元素的innerHTML到应用程序数据,并移除HTML字符串中危险字符
  4. ng-bind-template:规定使用膜拜替换的文本内容
  5. ng-blur:规定blur事件的行为
  6. ng-change:规定在内容改变时要执行的表达式
  7. ng-checked:规定元素是否被选中
  8. ......更多参见  AngularJS指令
  • AngularJS模块(Module)定义了AngularJS应用
  • AngularJS控制器用于控制AngularJS应用
  • ng-app指令定义了应用,ng-controller定义了控制器

 

6. 使用ngRoute进行视图之间的路由

$routeProvider.when('/hello',{        //$routeProvider提供路由, 当访问"hello"时会调用hello.html模板, 控制器HelloCtrl控制视图
    templateUrl: 'tpls/hello.html',
    controller:'HelloCtrl'
}).when('/list',{
    templateUrl:'tpls/bookList.html',
    controller:'BookListCtrl'
}).otherwise({
    redirectTo: '/hello'
})

 

7. ng官方推荐的模块切分方式:

                    app
                     |
    -----------------------------------------------
    |             |            |         |        |
controllers   directives   services   routes   filters
  1. 任何一个ng应用都是由控制器, 指令, 路由, 过滤器等有限的模块类型构成的
  2. 控制器, 指令, 服务, 路由, 过滤器分别放在一个模块里面(可借助于grunt合并)
  3. 用一个总的app模块作为入口点, 它依赖其他所有模块
     1 <!DOCTYPE html>
     2 <html ng-app="bookStore">
     3     <!-- ng-app只有一个,相当于main方法 -->
     4 <head>
     5     <title></title>
    <script>.....</script>
    6 </head> 7 <body> 8 <div ng-view> 9 10 </div> 11 </body> 12 </html>
      //controller.js
    1
    var bookStoreApp = angular.module('bookStoreApp',[ 2 'ngRoute','ngAnimate','bookStoreCtrls','bookStoreFilters', 3 'bookStoreServices','bookStoreDirectives' 4 ]);                                      //依赖注入. 模块之间的依赖的实现. 也可以加载angularjs自带的模块,比如ngAnimate, 记得在html中把script文件引入 5 6 bookStoreApp.config(function($routeProvider){ 7 $routeProvider.when('/hello',{         8 templateUrl: 'tpls/hello.html', 9 controller:'HelloCtrl' 10 }).when('/list',{ 11 templateUrl:'tpls/bookList.html', 12 controller:'BookListCtrl' 13 }).otherwise({ 14 redirectTo: '/hello' 15 }) 16 });
     1 //directives.js
     2 var bookStoreDirectives = angular.module('bookStoreDirectives', []);
     3 
     4 bookStoreDirectives.directive('bookStoreDirective_1', ['$scope',
     5     function($scope){}
     6 ]);
     7 
     8 bookStoreDirectives.directive('bookStoreDirective_2', ['$scope',
     9     function($scope){}
    10 ]);
     1 //services.js
     2 var bookStoreServices = angular.module('bookStoreServices', []);
     3 
     4 bookStoreServices.service('bookStoreService_1', ['$scope',
     5     function($scope){}
     6 ]);
     7 
     8 bookStoreServices.service('bookStoreService_2', ['$scope',
     9     function($scope){}
    10 ]);

     

 8. ng-bind

  如第2条所示的例子, 使用{{}}绑定数据时,可能会在页面加载过程中出现{{greeting.text}},使得页面不美观。 一个解决办法就是使用ng-bind

 1 <!DOCTYPE html>
 2 <html ng-app>
 3 <head>
 4     <title></title>
 5 </head>
 6 <body>
 7     <div ng-controller="HelloAngular">
 8         <p><span ng-bind="greeting.text"></span>,Angular</p>
 9     </div>
10 </body>
11 <script src="js/angular-1.3.0.js"></script>
12 <script src="HelloAngular_MVC.js"></script>
13 </html>

 

  所以,一般在首页加载时使用ng-bind。后面的页面可以使用{{}}来绑定

 

9. 双向绑定场景

  •  form表单
     1 <!DOCTYPE html>
     2 <html ng-app="userInfoModule">
     3 <!-- ng-app指令定义了一个AngularJS应用程序 -->
     4 
     5 <head>
     6     <meta charset="utf-8">
     7     <link rel="stylesheet" type="text/css" href="css\bootstrap-3.3.0-dist\dist\css\bootstrap.css">
     8     <script src="js/angular.js"></script>
     9     <script src="Form.js"></script>
    10     <title></title>
    11 </head>
    12 
    13 <body>
    14     <div class="panel panel-primary">
    15         <div class="panel-heading">
    16             <div class="panel-title">双向数据绑定</div>
    17         </div>
    18         <div class="panel-body">
    19             <div class="row">
    20                 <div class="col-md-12">
    21                     <form class="form-horizontal" role="form" ng-controller="UserInfoCtrl">
    22                         <div class="form-group">
    23                             <label class="col-md-2 control-label">
    24                                 邮箱:
    25                             </label>
    26                             <div class="col-md-10">
    27                                 <input class="form-control" type="email" placeholder="推荐使用126邮箱" ng-model="userInfo.email"></input>
    28                             </div>
    29                         </div>
    30                         <div class="form-group">
    31                             <label class="col-md-2 control-label">
    32                                 密码:
    33                             </label>
    34                             <div class="col-md-10">
    35                                 <input class="form-control" type="password" placeholder="只能是数字、字母、下划线" ng-model="userInfo.password"></input>
    36                             </div>
    37                         </div>
    38                         <div class="form-group">
    39                             <div class="col-md-offset-2 col-md-10">
    40                                 <div class="checkbox">
    41                                     <label>
    42                                         <input type="checkbox" ng-model="userInfo.autoLogin">自动登录
    43                                     </label>
    44                                 </div>
    45                             </div>
    46                         </div>
    47                         <div class="form-group">
    48                             <div class="col-md-offset-2 col-md-10">
    49                                 <button class="btn btn-default" ng-click="getFormData()">获取表单的值</button>
    50                                 <button class="btn btn-default" ng-click="setFormData()">设置表单的值</button>
    51                                 <button class="btn btn-default" ng-click="resetFormData()">重置表单</button>
    52                             </div>
    53                         </div>
    54                     </form>
    55                 </div>      
    56             </div>
    57         </div>
    58     </div>
    59 </body>
    60 </html>

     

     1 //这里等号右侧括号里第一个参数,模块的名称就是html中主函数入口“ng-app”的名称,即AngularJS应用的根元素
     2 //AngularJS模块定义应用
     3 var userInfoModule=angular.module('userInfoModule',[]);
     4 
     5 //AngularJS控制器控制应用
     6 userInfoModule.controller('UserInfoCtrl',['$scope', function($scope){
     7     $scope.userInfo={
     8         email:"25344528@qq.com",
     9         password:"12312313",
    10         autoLogin:true
    11     };
    12     $scope.getFormData=function(){
    13         console.log($scope.userInfo)
    14     };
    15     $scope.setFormData=function(){
    16         $scope.userInfo={
    17             email:'damoqiasss@124.sc',
    18             password:"ssss",
    19             autoLogin:false
    20         }
    21     };
    22     $scope.resetFormData = function(){
    23         $scope.userInfo={
    24             email: "123456@a.cc",
    25             password:"56",
    26             autoLogin:true
    27         }
    28     }
    29 }])

     

  • 例子2:修改样式: 不需要直接操作标签,而是给类绑定不同的值从而使得p标签取得不同的样式属性
     1 <!DOCTYPE html>
     2 <html>
     3 <head>
     4     <title></title>
     5 </head>
     6 <body>
     7 <!DOCTYPE html>
     8 <html ng-app="myCSSModule">
     9 <head>
    10     <meta charset="utf-8">
    11     <link rel="stylesheet" type="text/css" href="color.css">
    12     <title></title>
    13 </head>
    14 
    15 <body>
    16     <div ng-controller="CSSCtrl">
    17         <p class="text-{{color}}">测试CSS样式</p>
    18         <button class="btn btn-default" ng-click="setGreen()">绿色</button>
    19         <button class="btn btn-default" ng-click="setRed()">红色</button>
    20     </div> 
    21 </body>
    22 </html>
    23 </body>
    24     <script src="js/angular.js"></script>
    25     <script src="color.js"></script>
    26 </html>
     1 var module = angular.module("myCSSModule",[]);
     2 
     3 module.controller('CSSCtrl',['$scope', function($scope){
     4     $scope.setGreen = function(){
     5         $scope.color="green"
     6     };
     7     $scope.setRed = function(){
     8         $scope.color="red"
     9     }
    10 }])
    1 .text-red{
    2     color:red;
    3 }
    4 .text-green{
    5     color:green;
    6 }

     


    这里为了避免取不到color值得到text-null这样奇怪的东西,可以使用ng-class:
     1 <!DOCTYPE html>
     2 <html ng-app="MyCSSModule">
     3 <head>
     4     <meta charset="utf-8">
     5     <title></title>
     6     <style type="text/css">
     7         .error{
     8             background-color: red;
     9         }
    10         .warning{
    11             background-color: yellow;
    12         }
    13     </style>
    14 </head>
    15 <body>
    16     <div ng-controller="HeadController">
    17         <div ng-class='{error: isError, warning: isWarning}'>{{messageText}}</div>
    18         <!-- 如果isError是true就使用isError的样式,如果isWarning是true就使用warning的样式。error和warning定义在css中 -->
    19         <button ng-click="showError()">Simulate Error</button>
    20         <button ng-click="showWarning()">Simulate Warning</button>
    21     </div>
    22 </body>
    23 <script type="text/javascript" src="js/angular.js"></script>
    24 <script type="text/javascript">
    25     var module = angular.module("MyCSSModule",[]);
    26 
    27     module.controller("HeadController",["$scope",function($scope){
    28         $scope.isError = false;
    29         $scope.isWarning = false;
    30         $scope.showError = function(){
    31             $scope.isError = true;
    32             $scope.isWarning = false;
    33             $scope.messageText = "Error!";
    34         };
    35         $scope.showWarning = function(){
    36             $scope.isError = false;
    37             $scope.isWarning = true;
    38             $scope.messageText = "Warning!";
    39         };
    40     }])
    41 </script>
    42 </html>

 

  • 控制标签的显示与隐藏ng-show. 以及ng-hide与之相反
     1 <!DOCTYPE html>
     2 <html ng-app="MyCSSModule">
     3 <head>
     4     <meta charset="utf-8">
     5     <title></title>
     6     <style type="text/css">
     7         .error{
     8             background-color: red;
     9         }
    10         .warning{
    11             background-color: yellow;
    12         }
    13     </style>
    14 </head>
    15 <body>
    16     <div ng-controller="HeadController">
    17         <button ng-click="toggleMenu()">Toggle Menu</button>
    18         <ul ng-show="menuState.show">
    19         <!-- 使用menuState.show这个模型的值控制下面的li是否显示 -->
    20             <li ng-click='stun()'>Stun</li>
    21             <li ng-click='disintegrate()'>Disintegrate</li>
    22             <li ng-click='erase()'>Erase from history</li>
    23         </ul>
    24     </div>
    25 </body>
    26 <script type="text/javascript" src="js/angular.js"></script>
    27 <script type="text/javascript">
    28     var module = angular.module("MyCSSModule",[]);
    29 
    30     module.controller("HeadController",["$scope",function($scope){
    31         $scope.menuState={show:false};
    32         $scope.toggleMenu = function(){
    33             $scope.menuState.show = !$scope.menuState.show;
    34         };
    35     }])
    36 </script>
    37 </html>

     

  • 以及ngAnimate实现页面切换动画等

 10. 前端路由

  1. 使用前端路由的原因:
    1. AJax请求不会留下History记录
    2. 用户无法直接通过URL进入应用中的指定页面(保存书签、链接分享给朋友)
    3. Ajax对SEO是个灾难
  2. 路由的例子:
    // 要导入angular-route.js
     1 var bookStoreApp = angular.module('bookStoreApp',[
     2     'ngRoute','ngAnimate','bookStoreCtrls','bookStoreFilters',
     3     'bookStoreServices','bookStoreDirectives'
     4 ]);                                      //依赖注入. 模块之间的依赖的实现. 也可以加载angularjs自带的模块,比如ngAnimate, 记得在html中把script文件引入
     5 
     6 bookStoreApp.config(function($routeProvider){
     7     $routeProvider.when('/hello',{        
     8         templateUrl: 'tpls/hello.html',
     9         controller:'HelloCtrl'
    10     }).when('/list',{
    11         templateUrl:'tpls/bookList.html',
    12         controller:'BookListCtrl'
    13     }).otherwise({
    14         redirectTo: '/hello'
    15     })
    16 });
     

     这个AngularJS提供的路由机制不能实现路由的深层次嵌套。 可以从github上下载angular-ui-router

    <!-- tpl3/index.html -->
    <div class="container">
        <div ui-view="topbar"></div>
        <div ui-view="main"></div>
    </div>
    var routerApp = angular.module('routerApp',['ui.router']);
    routerApp.config(function($stateProvider,$urlRouterProvider){
        $urlRouterProvider.otherwise('/index');
        $stateProvider
            .state('index',{
                url: '/index',
                views: {
                    '': {
                        templateUrl:'tpls3/index.html'
                    },
                    'topbar@index' : {
                        templateUrl: 'tpl3/topbar.html'
                    },
                    'main@index': {
                        templateUrl: 'tpl3/home.html'
                    }
                }
            })
            .state('index.usermng'),{
                url: '/usermng',
                views: {
                    'main@index': {
                        templateUrl: 'tpls3/usermng.html',
                        controller: function($scope, $state){
                            $scope.addUserType = function(){
                                $state.go("index.usermng.addusertype");
                            }
                        }
                    }
                }
            }
    })  
  3. 前端路由的基本原理

    1. 哈希#
    2. HTML5中新的history API
    3. 路由的核心是给应用定义“状态”
    4. 使用路由机制会影响到应用的整体编码方式(需要预先定义好状态)
    5. 考虑兼容性问题与“优雅降级”

    

11. 指令

  1. 自定义指令hello:
    1 // HelloAngular_Directive.js
    2 var myModule = angular.module("MyModule",[]);
    3 myModule.directive("hello", function(){
    4     return {
    5         restrict: 'AEMC',       //四个字母分别表示:属性,元素,注释,类
    6         template: '<div>Hi everyone!</div>',
    7         replace: true
    8     }
    9 });

    使用hello指令的4种方法:

    <!DOCTYPE html>
    <html ng-app="MyModule">
        <head>
            <meta charset="utf-8">
            <title></title>
        </head>
    
        <body>
            <!-- 法1:使用元素 -->
            <hello></hello>
    
            <!-- 法2:使用 -->
            <div hello></div>
    
            <!-- 法3:使用样式类 -->
            <div class="hello"></div>
    
            <!-- 法4 -->
            <!-- directive:hello -->
            <div></div>
        </body>
        <script type="text/javascript" src="../test01/js/angular.js"></script>
        <script type="text/javascript" src="HelloAngular_Directive.js"></script>
    </html>
  2. restrict---匹配模式
    1. 默认使用“A” 属性的方式:  <div my-menu=Products></div>
      还有E-元素:   <my-menu title=Products></my-menu>
      C-样式类:    <div class=my-menu:Products></div>
      M-注释:      <!-- directive: my-menu Products -->
    2. 推荐使用元素和属性的方式使用指令
    3. 当需要创建带有自己的模板的指令时,使用元素名称的方式创建指令
    4. 当需要为已有的HTML标签增加功能时,使用属性的方式创建指令
  3. template--模板
    1. template
    2. templateURl
    3. templateCache
      ....myModule.directive("hello".......
             .....
             template: $templateCache.get("hello.html"),
             ....
  4. replace: 元素内部写的内容是否会被替换
  5. transclude
    template: "<div>Hello everyone!<div ng-transclude></div></div>
    //元素内部的内容替换到ng-transclude里面去
  6. 指令执行的三个阶段 & compile和link:
    1. 加载阶段:
      1. 加载angular.js,找到ng-app指令,确定应用的边界
    2. 编译阶段
      1. 遍历DOM,找到所有指令;
      2. 根据指令代码中的template、replace、transclue转换DOM结构
      3. 如果存在compile函数则调用
    3. 链接阶段
      1. 对每一条指令运行link函数
      2. link函数一般用来操作DOM,绑定事件监听器
    4. 关于compile和link:
      1. compile函数用来对模板自身进行转换, 而link函数负责在模型和视图之间进行动态关联;
      2. 作用域在链接阶段才会被绑定到编译之后的link函数上
      3. compile函数仅仅在编译阶段运行一次,而对于指令的每个实例,link函数都会执行一次
      4. compile可以返回preLink和postLink函数,而link函数只会返回postLink函数
      5. 如果需要修改DOM结构,应该在postLink中来做这件事情,而如果在preLink中做这件事情会导致错误
      6. 大多数时候我们只要编写link函数即可
  7. 使用directive和Controller绑定DOM事件
     1 <!-- Directive&Controller.html -->
     2 <!DOCTYPE html>
     3 <html ng-app="MyModule">
     4 <head>
     5     <meta charset="utf-8">
     6     <title></title>
     7 </head>
     8 <body>
     9     <div ng-controller="MyCtrl">
    10         <loader>滑动加载</loader>
    11     </div>
    12 </body>
    13 <script type="text/javascript" src="../test01/js/angular.js"></script>
    14 <script type="text/javascript" src="Directive&Controller.js"></script>
    15 </html>
    //Directive&Controller.js
    var myModule = angular.module("MyModule",[]);
    
    myModule.controller('MyCtrl',['$scope', function($scope){
        $scope.loadData = function(){
            console.log("加载数据中....");
        }
    }]);
    
    myModule.directive("loader", function(){
        return {
            restrict: 'AE',    
            link:function(scope,element,attr){
                element.bind("mouseenter",function(){
                    scope.loadData();
                    //或者用下面的方法
                    scope.$apply('loadData()');
                })
            }
        };
    });
    如果要在不同的控制器中使用指令调用不同的函数,则可以在自定义的元素中定义不同的属性来规定调用的方法,比如:
     1 <!-- Directive&Controller.html -->
     2 <!DOCTYPE html>
     3 <html ng-app="MyModule">
     4 <head>
     5     <meta charset="utf-8">
     6     <title></title>
     7 </head>
     8 <body>
     9     <div ng-controller="MyCtrl1">
    10         <loader howToLoad="loadData1()">滑动加载</loader>
    11     </div>
    12     <div ng-controller="MyCtrl2">
    13         <loader howToLoad="loadData2()">滑动加载</loader>
    14     </div>
    15 </body>
    16 <script type="text/javascript" src="../test01/js/angular.js"></script>
    17 <script type="text/javascript" src="Directive&Controller.js"></script>
    18 </html>
    //Directive&Controller.js
    var myModule = angular.module("MyModule",[]);
    
    myModule.controller('MyCtrl1',['$scope', function($scope){
        $scope.loadData1 = function(){
            console.log("加载数据中....111");
        }
    }]);
    
    myModule.controller('MyCtrl2',['$scope', function($scope){
        $scope.loadData2 = function(){
            console.log("加载数据中....222");
        }
    }]);
    
    myModule.directive("loader", function(){
        return {
            restrict: 'AE',    
            link:function(scope,element,attr){
                element.bind("mouseenter",function(){
                    scope.$apply(attr.howtoload);       //注意在定义属性中用的的howToLoad的驼峰命名法,在js里只要用小写就可
                })
            }
        };
    });
  8. Directive&Directive
    <!-- Directive&Directive.html -->
    <!DOCTYPE html>
    <html ng-app="MyModule">
    <head>
        <meta charset="utf-8">
        <title></title>
        <link rel="stylesheet" type="text/css" href="..\test01\css\bootstrap-3.3.0-dist\dist\css\bootstrap.css">
    </head>
    <body>
        <div class="row">
            <div class="col-md-3">
                <superman strength>动感超人----力量</superman>
            </div>
        </div>
        <div class="row">
            <div class="col-md-3">
                <superman strength speed>动感超人2----力量+敏捷</superman>
            </div>
        </div>
        <div class="row">
            <div class="col-md-3">
                <superman strength speed light>动感超人3----力量+敏捷+发光</superman>
            </div>
        </div>
    </body>
    <script type="text/javascript" src="../test01/js/angular.js"></script>
    <script type="text/javascript" src="Directive&Directive.js"></script>
    </html>
    //Directive&Directive.js
    var myModule = angular.module("MyModule",[]);
    myModule.directive("superman", function(){
        return {
            scope: {},
            restrict: 'AE',
            //指令内部的controller,目的是给指令暴露出public方法给指令外部调用的
            controller: function($scope){
                $scope.abilities = [];
                this.addStrength = function(){
                    $scope.abilities.push("strength");
                };
                this.addSpeed = function(){
                    $scope.abilities.push("speed");
                };
                this.addLight = function(){
                    $scope.abilities.push("light");
                };
            },
            //如果想定义暴露出的public方法给指令外部调用就使用controller
            //而link是用于处理指令内部的一些事物,比如给元素绑定事件,改变属性等
            link: function(scope,element,attrs){
                element.addClass('btn btn-primary');
                element.bind('mouseenter',function(){
                    console.log(scope.abilities);
                });
            }
        }
    });
    myModule.directive("strength", function(){
        return {
            //require意思是strength指令是依赖superman指令的。link就可以写第四个参数,则link中就可以直接调用supermanCtrl中暴露出来的方法了
            require: '^superman',
            link: function(scope, element, attrs, supermanCtrl){
                supermanCtrl.addStrength();
            }
        }
    });
    
    myModule.directive("speed", function(){
        return {
            require: '^superman',
            link: function(scope, element, attrs, supermanCtrl){
                supermanCtrl.addSpeed();
            }
        }
    });
    
    myModule.directive("light", function(){
        return {
            require: '^superman',
            link: function(scope, element, attrs, supermanCtrl){
                supermanCtrl.addLight();
            }
        }
    });
  9. 独立scope
     1 <!-- IsolateScope.html -->
     2 <!DOCTYPE html>
     3 <html ng-app="MyModule">
     4 <head>
     5     <meta charset="utf-8">
     6     <title></title>
     7     <link rel="stylesheet" type="text/css" href="..\test01\css\bootstrap-3.3.0-dist\dist\css\bootstrap.css">
     8 </head>
     9 <body>
    10     <hello></hello>
    11     <hello></hello>
    12     <hello></hello>
    13     <hello></hello>
    14 </body>
    15 <script type="text/javascript" src="../test01/js/angular.js"></script>
    16 <script type="text/javascript" src="IsolateScope.js"></script>
    17 </html>
    //IsolateScope.js
    var myModule = angular.module("MyModule",[]);
    myModule.directive("hello", function(){
        return {
            restrict: 'AE',
            scope: {},      //如果不加这个配置项,一个改变其他都会改变
            template: '<div><input type="text" ng-model="userName"/>{{userName}}</div>',
            replace: true
        }
    });
    scope的绑定策略
    1. @: 把当前属性作为字符串传递。 你还可以绑定来自外层scope的值,在属性值中插入{{}}即可
       1 <!-- ScopeAt.html -->
       2 <!DOCTYPE html>
       3 <html ng-app="MyModule">
       4 <head>
       5     <meta charset="utf-8">
       6     <title></title>
       7     <link rel="stylesheet" type="text/css" href="..\test01\css\bootstrap-3.3.0-dist\dist\css\bootstrap.css">
       8 </head>
       9 <body>
      10     <div ng-controller="MyCtrl">
      11         <drink flavor="{{ctrlFlavor}}"></drink>
      12     </div>
      13 </body>
      14 <script type="text/javascript" src="../test01/js/angular.js"></script>
      15 <script type="text/javascript">
      16     var myModule = angular.module("MyModule",[]);
      17     myModule.controller('MyCtrl', ['$scope', function($scope){
      18         $scope.ctrlFlavor = "百威";
      19     }])
      20     // myModule.directive("drink", function(){
      21     //     return {
      22     //         restrict: 'AE',
      23     //         template:"<div>{{flavor}}</div>",
      24     //         link: function(scope, element, attrs){
      25     //             scope.flavor = attrs.flavor;
      26     //         }
      27     //     }
      28     // })
      29     //以上可以直接写作:
      30     myModule.directive("drink", function(){
      31         return {
      32             restrict:'AE',
      33             scope: {
      34                 flavor: '@'
      35             },
      36             template: "<div>{{flavor}}</div>"
      37         }
      38     })
      39 </script>
      40 </html>
    2. =: 与父scope中的属性进行双向绑定
       1 <!-- ScopeEqual.html -->
       2 <!DOCTYPE html>
       3 <html ng-app="MyModule">
       4 <head>
       5     <meta charset="utf-8">
       6     <title></title>
       7     <link rel="stylesheet" type="text/css" href="..\test01\css\bootstrap-3.3.0-dist\dist\css\bootstrap.css">
       8 </head>
       9 <body>
      10     <div ng-controller="MyCtrl">
      11         Ctrl:
      12         <br>
      13         <input type="text" ng-model="ctrlFlavor">
      14         <br>
      15         Directive:
      16         <br>
      17         <drink flavor="ctrlFlavor"></drink>
      18     </div>
      19 </body>
      20 <script type="text/javascript" src="../test01/js/angular.js"></script>
      21 <script type="text/javascript">
      22     var myModule = angular.module("MyModule",[]);
      23     myModule.controller('MyCtrl', ['$scope', function($scope){
      24         $scope.ctrlFlavor = "百威";
      25     }])
      26     myModule.directive("drink", function(){
      27         return {
      28             restrict:'AE',
      29             scope: {
      30                 flavor: '='
      31             },
      32             template: '<input type="text" ng-model="flavor"/>'
      33         }
      34     })
      35 </script>
      36 </html>
    3. &: 传递一个来自父scope的函数,稍后调用

       1 <!-- ScopeAnd.html -->
       2 <!DOCTYPE html>
       3 <html ng-app="MyModule">
       4 <head>
       5     <meta charset="utf-8">
       6     <title></title>
       7     <link rel="stylesheet" type="text/css" href="..\test01\css\bootstrap-3.3.0-dist\dist\css\bootstrap.css">
       8 </head>
       9 <body>
      10     <div ng-controller="MyCtrl">
      11         <greeting greet="sayHello(name)"></greeting>
      12         <greeting greet="sayHello(name)"></greeting>
      13         <greeting greet="sayHello(name)"></greeting>
      14     </div>
      15 </body>
      16 <script type="text/javascript" src="../test01/js/angular.js"></script>
      17 <script type="text/javascript">
      18     var myModule = angular.module("MyModule",[]);
      19     myModule.controller('MyCtrl', ['$scope', function($scope){
      20         $scope.sayHello = function(name){
      21             alert("Hello "+name);
      22         }
      23     }])
      24     myModule.directive("greeting", function(){
      25         return {
      26             restrict:'AE',
      27             scope: {
      28                 greet: '&'
      29             },
      30             template: '<input type="text" ng-model="userName"/><br/>' +
      31                       '<button class="btn btn-default" ng-click="greet({name:userName})">Greeting</button><br>'
      32         }
      33     })
      34 </script>
      35 </html>
  10. form指令
    1. HTML原生的form表单是不能嵌套的,而Angular封装之后的form可以嵌套
    2. Angular为form扩展了自动校验、防止重复提交等功能;
    3. Angular对input元素的type进行了校验,一共提供了以下10种类型:
      text, number, url, email, radio, checkbox, hidden, button, submit, reset
    4. Angular为表单内置了4种CSS样式:
      ng-valid, ng-invaid, ng-pristine, ng-dirty 
    5. 内置校验器:

      require, minlength, maxlength
       1 <!-- FormBasic.html -->
       2 <!DOCTYPE html>
       3 <html ng-app="TestFormModule">
       4 <head>
       5     <meta charset="utf-8">
       6     <script type="text/javascript" src="../test01/js/angular.js"></script>
       7 </head>
       8 <body>
       9     <form name="myForm" ng-submit="save()" ng-controller="TestFormModule">
      10         <input type="text" name="userName" ng-model="user.userName" required/>
      11         <input type="password" name="password" ng-model="user.password" required/>
      12         <input type="submit" ng-disabled="myForm.$invalid" />
      13     </form>
      14 </body>
      15 <script type="text/javascript">
      16     var myModule = angular.module("TestFormModule",[]);
      17     myModule.controller("TestFormModule", function($scope){
      18         $scope.user={
      19             userName:'xxxxx',
      20             password:''
      21         };
      22         $scope.save=function(){
      23             alert("save!");
      24         }
      25     })
      26 </script>
      27 </html>
  11. 自定义指令
     1 <!-- Expander.html -->
     2 <!DOCTYPE html>
     3 <html ng-app="expanderModule">
     4 <head>
     5     <meta charset="utf-8">
     6     <script type="text/javascript" src="../test01/js/angular.js"></script>
     7 </head>
     8 <body>
     9     <div ng-controller="SomeController">
    10         <expander class="expander" expander-title='title'>
    11             {{text}}
    12         </expander>
    13     </div>
    14 </body>
    15 <script type="text/javascript">
    16     var myModule = angular.module("expanderModule",[]);
    17     myModule.directive("expander", function(){
    18         return {
    19             restrict: 'EA',
    20             replace: true,
    21             transclude: true,
    22             scope: {
    23                 title : '=expanderTitle'
    24             },
    25             template: '<div>'
    26                     + '<div class="title" ng-click="toggle()">{{title}}</div>'
    27                     + '<div class="body" ng-show="showMe" ng-transclude></div>'
    28                     + '</div>',
    29             link: function(scope, element, attrs){
    30                 scope.showMe = false;
    31                 scope.toggle = function(){
    32                     scope.showMe = !scope.showMe;
    33                 }
    34             }
    35         }
    36     });
    37     myModule.controller('SomeController', function($scope){
    38         $scope.title = '点击展开';
    39         $scope.text = '这里是内部的内容';
    40     });
    41 </script>
    42 </html>
  12. 第三方指令库:angular-ui

  

12. Service和Provider:

  1. 使用$http服务
    <!-- HTTPbasic.html -->
    <!DOCTYPE html>
    <html ng-app="MyModule">
    <head>
        <meta charset="utf-8">
        <script type="text/javascript" src="../test01/js/angular.js"></script>
    </head>
    <body>
        <div ng-controller="LoadDataCtrl">
            <ul>
                <li ng-repeat="user in users">
                    {{user.name}}
                </li>
            </ul>
        </div>
    </body>
    <script type="text/javascript">
        var myModule = angular.module("MyModule",[]);
    
        myModule.controller("LoadDataCtrl", ['$scope','$http',function($scope,$http){
            $http({
                method: 'GET',
                url: 'data.json'
            }).success(function(data, status, headers, config) {
                console.log("success...");
                console.log(data);
                $scope.users=data;
            }).error(function(data, status, headers, config) {
                console.log("error...");
            });
            //这里会报错:$http(...).success is not a function。好像现在得用$http().then()function了?
        }]);
    </script>
    </html>
  2. 创建自己的Service
  3. Service的特性
    1. Service都是单例
    2. Service由$injector负责实例化
    3. Service在整个应用的生命周期中存在,可以用来共享数据
    4. 在需要使用的地方利用依赖注入机制注入Service
    5. 自定义的Service需要写在内置的Service后面
    6. 内置Service的命名以$符号开头,自定义Service应该避免
  4. Service,Factory,Provider本质上都是Provider
    function provider(name, provider_){
        if(isFunction(provider_)){
            provider_ = providerInjector.instantiate(provider_);
        }
        if(!provider_.$get){
            throw Error('provider '+name+' must define $get factory...');
        }
        return providerCache[name + providerSuffix] = provider_;
    }
    Provider模式是“策略模式”+“抽象工厂模式”的混合体
  5. 使用$filter服务
    1. $filter是用来进行数据格式化的专用服务
    2. AngularJS内置了9个filter:
      currency(格式化货币),data(日期),filter,json,limitTo,lowercase,number,orderBy,uppercase
    3. filter可以嵌套使用(用管道符号|分隔)
    4. filter是可以传递参数的
    5. 用户可以定义自己的filter
       1 <!DOCTYPE html>
       2 <html ng-app="MyModule">
       3 <head>
       4     <meta charset="utf-8">
       5     <script type="text/javascript" src="../test01/js/angular.js"></script>
       6 </head>
       7 <body>
       8     {{ 1304375948024 | date}}
       9     <br>
      10     {{ 1304375948024 | date:"MM/dd/yy @ h:mma"}}
      11     <br>
      12     {{ 1304375948024 | date:"yyyy-MM-dd hh:mm::ss"}}
      13 </body>
      14 <script type="text/javascript">
      15     var myModule = angular.module("MyModule",[]);
      16 </script>
      17 </html>
  6. 其他内置的Service介绍

 13. 核心原理解析

  1. AngularJS的启动过程分析
  2. 依赖注入原理分析:Provider与Injector
  3. 指令的执行过程分析
  4. $scope与双向数据绑定分析

posted on 2017-02-20 23:05  杠子  阅读(1342)  评论(0编辑  收藏  举报

导航