我爱编程

Angular

2017-12-05  本文已影响0人  majun00

title: Angular
tags:


Angular

简介

SPA

//根据url中锚点值的变化,动态的请求不同的数据
<a href="#find"></a>
window.addEventListener("hashchange",function(){
//hashchange监听url中锚点值变化的事件
    var hash= location.hash;
    //location.hash, location.href
    switch(hash){
        case '#find':
            $.get('find.json',function(data){
                console.log(data);
            },'json');
        break;
        case:...;
    }
})

指令

<!-- 约定ng-app -->
<body ng-app>
    <!-- 获取值ng-model -->
    <input type="text" ng-model="val">
    <!-- 添加点击事件ng-click -->
    <input type="text" value="+1" ng-click="myVal-0+1">
    <div>{{val}}</div>
    <!-- 初始化ng-init -->
    <div ng-init="val=1"></div>
</body>
<!-- 引包 -->
<script src="./libs/angular.js"></script>

模块

控制器

双向数据绑定

<body ng-app="hello">
    <input type="text" ng-model="name">
    <span>{{name}}</span>
    <input type="button" value="打印值" ng-click="getName()">
    <input type="button" value="改变为小红" ng-click="setName()">
    <script src="./libs/angular.js"></script>
    <script>
        // 创建模块
        var app=angular.module('hello',[]);
        // 创建控制器
        app.controller('helloController',function($scope){
            // 初始化数据模型
            $scope.name="小明";
            // 初始化行为模型
            $scope.getName=function(){
                console.log($scope.name)
            };
            $scope.setName=function(){
                $scope.name="小红"
            }
        })
    </script>
</body>

MVC 思想

<body ng-app="app">
  <!-- view 开始 -->
  <table ng-controller="demoController">
    <tr><td>用户名: <input type="text" ng-model="username"></td></tr>
    <tr><td>密码: <input type="text" ng-model="userpwd"></td></tr>
    <tr><td>用户类型:
        <select ng-model="type">
          <option value="tmp01">学生</option>
          <option value="tmp02">老师</option>
          <option value="tmp03">校长</option>
        </select>
    </td></tr>
    <tr><td>注册协议: <input type="checkbox" ng-model="isAgree"></td></tr>
    <tr><td><input type="button" value="注册" ng-click="register()"></td></tr>
    <tr><td>{{msg}}</td></tr>
  </table>
  <!-- View 结束 -->
  <script src="libs/angular.js"></script>
  <script>
    var app = angular.module('app',[])
    // Controller 开始
    app.controller('demoController',function($scope){
      // 初化数据模型
      $scope.username = '';
      $scope.usertype = '';
      $scope.userpwd = '';
      $scope.isagree = false;
      $scope.msg = ''
      // 初始化行为模型
      $scope.register = function(){
        if($scope.userpwd.length<6){
          $scope.msg='密码太短,不安全!';
          return
        }
        // 准备存储数据
        // 调用用Model里的方法
        var u = new User($scope.username,$scope.userpwd,$scope.type);
        var result = u.save();
        if(result){
          $scope.msg = '注册成功!'
        }else{
          $scope.msg = '注册失败!'
        }
      }
    })
    // Controller 结束
    // Model 开始
    function User(name,pwd,type){
      this.name = name;
      this.pwd = pwd;
      this.type = type
    }
    User.prototype.save = function(){
      // 判断用户名是否存在
      var str = localStorage.getItem('myusers')||'[]';
      // 注意'[]'
      var arr = JSON.parse(str);
      for (var i = 0; i < arr.length; i++) {
        if(arr[i].name===this.name){
          return 
        }
      }
      arr.push({name:this.name,pwd:this.pwd,type:this.type});
      localStorage.setItem('myusers',JSON.stringify(arr));
      return true
    }
  </script>
</body>

Angular开发流程回顾

augular.element (不推崇)

$scope

正是因为$scope在Angular中大量使用甚至盖过了C(控制器)的概念,所以很多人把Angular称之为MVVM框架,$scope 实际上就是MVVM中所谓的VM(视图模型)

控制器

传统的方式创建控制器

    // 创建控制器(1.2.x版本)
    // angular会把全局的函数当作控制器
    function demoController($scope){
      $scope.name = '小明'
    }

面向对象的方式创建控制器

<!-- 这里的obj 代表控制器中回调函数new 出的对象 -->
<div ng-controller="demoController as obj">
  <p>{{myname}}</p>
  <p>{{obj.name}}</p>
</div>
    var app = angular.module('myApp', [])
    // angular会把这二个参数当作构造函数使用
    app.controller('demoController', function($scope){
      $scope.myname='小红'
      this.name = '小明'
    })

安全的方式创建控制器

    // 把第二个参数改为一个数组,在数组把我们需要的参数的名字写上
    // 回调函数就写在数组的最后一个元素上
    // 数据中传入的元素的顺序,要和function的中顺序一一对应
    app.controller('demoController',['$scope','$log',function($scope,$log){
      $scope.msg = 'hello World!'
      $log.log('哈哈哈哈!')
      //注意$log.log()
    }])
// 注意是'$scope'

指令

ng-bind

解决表达式闪烁问题,浏览器不会把标签的属性显示出来,angular会把ng-bind对应的数据显示到所在标签中间

ng-cloak

也可以解决表达闪烁问题,注意ng-cloak是样式,我们要先给ng-cloak设置display:none,angular在解析表达式之后会把页面上的ng-cloak样式移除,这样ng-cloak对应的样式就不生效了

ng-repeat

<body ng-app="myApp">
  <div ng-controller="demoController">
    <ul>
      <li ng-repeat="item in users" >
        {{item.name}} {{item.age}}
      </li>
    </ul>
  <ul>
    <li ng-repeat="item in obj">
      {{item.name}} {{item.age}}
    </li>
  </ul>
  <ul>
    <li ng-repeat="item in arr track by $index">
      {{item}} {{$index}}
    </li>
  </ul>
  </div>
  <script src="libs/angular.js"></script>
  <script>
    var app = angular.module('myApp', [])
    app.controller('demoController',['$scope',function($scope){
      $scope.users = [
        {name:'小明',age:18},
        {name:'小红',age:18},
        {name:'小朋',age:28},
        {name:'小月',age:19},
        {name:'小黑',age:18},
        {name:'小白',age:20}
      ]
      $scope.obj = {
        xm:{name:'小明',age:18},
        xh:{name:'小红',age:28},
        xt:{name:'小天',age:10},
        xy:{name:'小月',age:38}
      }
      $scope.arr = [1,2,3,4,5,1]
    }])
    // 注意:item in arr track by $index
  </script>
</body>

      <li class="{{ $odd ?'red':'green'}}" ng-repeat="item in data">
        {{item.name}},{{item.age}}
      </li>

ng-class

    <!--  ng-class,动态的添加class样式,
      以对象的形式书写,angular会把属性值为true的属性名当作样式添加到class-->
    <li ng-class="{red:item.age>=20, green:item.age>=10&&item.age<20,blue:item.age<10}" ng-repeat="item in data">
      {{item.name}},{{item.age}}
    </li>
    <!-- 注意格式ng-class="{classname:true,classname2:true,...}" -->

ng-show/ng-hide

<body ng-app="myApp">
  <div ng-controller="demoController">
    <p ng-show="isShowing">hello</p>
    <button ng-click="showOrHide()">显示/隐藏</button>
  </div>
  <script src="libs/angular.js"></script>
  <script>
    var app = angular.module('myApp', [])
    app.controller('demoController', ['$scope', function($scope){
        $scope.isShowing= true;
        $scope.showOrHide=function(){
          $scope.isShowing = !$scope.isShowing
        }
    }])
  </script>
</body>

ng-if

ng-switch

<body ng-app="myApp">
<div ng-controller="demoController">
    <div ng-switch="name">
        <div ng-switch-when="小明">
            我是小明
        </div>
    </div>
</div>
<script src="libs/angular.js"></script>
<script>
    var app = angular.module('myApp', [])
    app.controller('demoController',['$scope', function($scope){
        $scope.name = '小明'
    }])
    // 注意ng-switch-when
</script>

其他常用指令

常用事件指令

指令的其他使用方式

todomvc案例

todomvc功能分析

  1. 任务的展示
  2. 添加任务
  3. 删除任务
  4. 修改任务内容
  5. 切换任务完成与否的状态
  6. 批量切换任务完成与否的状态
  7. 显示未完成的任务数
  8. 清除所有已完成任务
    • 注意: 在循环删除数组长度,会导致循环条件改变,也会导致元素原来的索引改变
  9. 切换显示不同状态的任务

过滤器(filter)

  <!-- 在数据模型后加上|  再加上过滤器的名字 
        也可以在过滤器名字后指定参数,参数是写在冒号后面的-->
  <p>{{money | currency : '¥'}}</p>
  <p>{{myDate | date : 'yyyy年MM月dd日 HH:mm:ss'}}</p>
  <!-- limitTo第一个参数,表明显示多少个字,第二个参数表示,从第几个字开始显示(索引从0开始) -->
  <p>{{msg | limitTo : 5 : 2}}...</p>
 <!--  json格式化显示json数据,参数指定缩近的长度 -->
 <pre>{{myJson | json : 8}}</pre>
 <!-- orderBy对数据进行排序,参数,给+号就按正序排,- 就按倒序排 -->
 <span ng-repeat="item in arr | orderBy:'-'">{{item}},</span>
     app.controller('filterController', ['$scope','$filter',function($scope,$filter){// $filter 需要在控制器的回调中传入
        $scope.money = 9998;
        // 可以调用不同的过滤器得到相应的结果
        // 参数是一个过滤器的名字
        // 返回值是一个方法
        // 后面括号里的第一个参数是需要处理的数据
        // 后面括号里的的第二个参数是当前过滤器本身需要的参数
        // $filter('过滤器名称')(需要过滤的数据,filter 参数)
        $scope.result =  $filter('currency')($scope.money,'¥')
    }])

数据模型 | filter : {key:value}

<body ng-app="filterApp" ng-controller="fitlerController">
  <div>
    <input type="text" ng-model="search">
    <ul>
      <li ng-repeat="item in todos | filter : {completed:true} ">
        {{item.name}},{{item.completed}}
      </li>
      <!-- <li ng-repeat="item in todos | filter : search ">
        {{item.name}},{{item.completed}}
      </li> -->
    </ul>
    <!--  如果指定一个布尔值,或者字符串就是全文匹配 -->
    <!-- 数据精确过滤  参数:1、scope的属性,2、自定的字符串  3、自定的对象 {}-->
    <!-- 会到对应的todos中寻找,如果当前元素有completed属性且值 为true就会被显示出来。(只会到completed属性中寻找) -->
  </div>
  <script src="libs/angular.js"></script>
  <script>
      var app = angular.module('filterApp', [])
      app.controller('fitlerController', ['$scope',function($scope){
          $scope.search='';
          $scope.todos = [
              {id:1,name:'吃饭',completed:true},
              {id:2,name:'睡觉吃饭',completed:true},
              {id:3,name:'打豆豆',completed:false},
              {id:4,name:'学习', completed:true},
              {id:5,name:'喝水,true',completed:false}
          ]
      }])
  </script>
</body>

$watch 监视数据模型的变化

<body ng-app="hello">
  <div ng-controller="helloController">
    <input type="text" ng-model="name">
    <input type="text" ng-model="age">
    <button>测试</button>
  </div>
  <script src="libs/angular.js"></script>
  <script>
    var app = angular.module('hello', [])
    app.controller('helloController',['$scope',function($scope){
      $scope.name = '小明'
      $scope.age = 18
      // $watch可以用来监视数据模型的变化
      // 第一个参数: 数据模型对应的名字(字符串形式)
      // 第二个参数: 相应的数据模型变化就会调用这个函数
      // 默认会直接执行一次回调函数
      $scope.$watch('name',function(now,old){
        // 第一个参数是变化后的值
        // 第二个参数是变化前的值
        console.log(now,old)
      })

      $scope.getAge = function(){
        return $scope.age
      }
      // 也能够监视$scope.属性中的方法的返回值
      $scope.$watch('getAge()',function(now,old){
        console.log(now,old)
      })
      // $watch监视的是$scope的属性,如果是一个普通变量是无法监视的
      // function getName(){
      //   return $scope.name
      // }
      // $scope.tmp = getName
      // $scope.$watch('tmp()',function(now,old){
      //   console.log(now,old)
      // })
    }])
  </script>
</body>

自定义属性

<body ng-app="directiveApp">
  <!-- 以属性形式使用 -->
  <!-- <div my-btn></div> -->
  <!-- 以样式名形式使用 -->
  <!-- <div class="my-btn"></div> -->
  <!-- 以自定义标签形式使用 -->
  <my-btn mystyle="red">咦</my-btn>
<script id='tpl' type='text/ng-template'>
  <div>
    <!-- <p class="tmp"> 我是在模板里定义的p,没有写ng-transclude</p> -->
    <p class="{{mystyle}}">hello</p>
    <p ng-transclude>hey</p>
  </div>
</script>
<script src="libs/angular.js"></script>
<script>
    var app = angular.module('directiveApp', [])
    // 创建自定义指令 directive
    // 第一个参数:是指令的名字,必须是驼峰命名法,使用时把大写改成小写,在原来大写前加上-
    // 第二个参数:和控制器的第二个参数类似
    app.directive('myBtn', [function(){
        // 在这里直接return 一个对象就可以了
        return {
            // template:'hello'
            // templateUrl:'template.html'
            templateUrl:'tpl',
            restrict:'ACE',
            replace:true,
            transclude: true,
            scope:{
              // tmp:'@mystyle',
              mystyle:'@',
            },
            link:function(scope,element,attributes){
                scope.msg="hello"
                console.log(element)
                element.on('click',function(){
                    alert('你点我了!')
                })
                console.log(attributes)
            }
        }
    }])
    //注意directive,type='text/ng-template',transclude
</script>
</body>

自定义指令中回调里返回的对象的属性

服务

  var app = angular.module('service',[])
  // 第一个参数:服务的名字
  // 第二个参数里的function: 
  // angular会把这个function当作构建函数,angular会帮助我们new这个构建函数,然后得到一个对象
  app.service('MyService', [function(){
    this.name = '小明'
  }])
  var app = angular.module('todosApp', ['service'])
  app.controller('todosController',['MyService',function(MyService){
    // 这个MyService就是,对应的'MyService'时的回调函数new出的对象
    console.log(MyService)
}])

路由

路由使用

<body ng-app="myApp">
<div ng-view></div>
<script src="libs/angular.js"></script>
<script src="libs/angular-route.js"></script>
<script>
    var app=angular.module('myApp',['ngRoute'])
    //注意['ngRoute']

    // $location.url()可以得到url中锚点值#后的部分
    // 配置路由规则
    app.config(['$routeProvider',function($routeProvider){
    // 第一个参数:对应的url中锚点值
    // 当angular检测到url中锚点变为/a,就会把template对应的内容插入到页面拥有ng-view指令的标签中
        $routeProvider
            .when('/a',{
                template:'<div>{{msg}}</div>',
                controller:'demoController'
                // 指定一个控制器的名字,
                // 当前url中锚点值为/a时就会执行控制器中的回调函数
                // 我们可以直接在template/templateUrl对应的模板中使用该控制器中对应的$scope属性值
            })
            .when('/b',{
                template:'<div>hello</div>'
            })
    }])
    app.controller('demoController',['$scope',function($scope){
        $scope.msg="hi";
    }])
</script>
</body>

路由参数

<body ng-app="myApp">
  <div ng-view></div>
  <script src="libs/angular.js"></script>
  <script src="libs/angular-route.js"></script>
  <script>
    var app=angular.module('myApp',['ngRoute']);
    app.config(['$routeProvider',function($routeProvider){
      $routeProvider.when('/company/:myname?',{
        //在原有规则中可以加冒号:,:号后跟上一个名字(相当于变量名,当前位置可以写成任意的值,但是必须要有) ?号表示当前位置如果没有值,也可以匹配到
        template:'<div>{{msg}}</div>',
        controller:'demoController'
      })
      .otherwise({redirectTo:'/company/a'})
      // 当不匹配when方法对应的规则时,就会匹配otherwise对应的规则
    }])
    app.controller('demoController',['$scope','$routeParams',function($scope,$routeParams){
      $scope.data={
        a:'hello',
        b:'hi',
        c:'hey'
      };
      $scope.msg=$scope.data[$routeParams.myname]
      // 在控制器中可以通过$routeParams得到对应的值
    }])
  </script>
</body>
上一篇 下一篇

猜你喜欢

热点阅读