天天看点

AngularJS基础学习笔记

  • Angular是什么?优点?
    • 前端MVC框架
    • 克服了HTML在构建应用上的诸多不足
  • 特点
    • jQuery以dom为驱动(核心)
    • angularjs以数据和逻辑作为驱动(核心)
    • 最核心的是:模块化、双向数据绑定、语义化标签、依赖注入
  • MVC是一种开发模式
    • M-->model一般用来处理数据(读取/设置),一般用来操作数据库
    • V-->view一般用来展示数据,比如通过HTML展示
    • C-->controller一般用做连接模型和视图的桥梁
  • thinkPHP:

    __PUBLIC__==>得到thinkPHP中的public的路径 assign(title,$title)$title内容分配给title:数据分配 assign(赋值给谁,变量)

  • 模块化
    • 一旦引入angularJS框架,就会提供一个全局的对象:angular,此对象下有N多方法,其中module方法可以帮我们创建一个模块

      var App = angular.module('App',[]);

      App就是新创建的模块,这个模块又是一个对象,此对象下又有N多方法,可以实现具体业务逻辑

      所以真正实现业务的是App,angular.module()只是构造一个模块

    • App.controller('DemoCotroller',['$scope',function($scope){}]);第一个参数是控制器名称
      • 使用套路:

        要使用ng-app指定联合那个模块,使用ng-controller指定是那个控制器

      • 使用方法:
        <div class="box" **ng-app='App'**>
              <div **ng-controller='DemoCotroller'**>
             <h1>{{name}}在{{school}}学习使用angularjs</h1>
              </div>
           </div>
           <!-- 引入angularJS框架 -->
           <script src="js/angular.js"></script>
           <script> 
           **var App = angular.module('App',[]);**
           **App.controller('DemoCotroller',['$scope',function($scope){
            // $scope是一个空的对象,此对象就是model
            $scope.name = 'zs';
            $scope.shool = '微博';
           }]);**
           </script>
                   
  • 指令:
    • 内置指令:
      • ng-repeat='(key,数组别名) in 数组名' {{数组别名}}可以得到一个个的数组内容 {{key}}可以得到索引
      • ng-app:制定应用根元素,至少有一个元素指定此属性
      • ng-controller:指定控制器
      • ng-show :控制元素是否显示,true显示
      • ng-hide:控制元素是否隐藏,true隐藏
      • ng-if:控制元素是否存在,true存在、false不存在
      • ng-src:增强图片路径
      • ng-href:增强地址
      • ng-class='{类名:布尔值}':控制类名,true类名有效,false类名无效
        • 值可以是字符串,对象或者一个数组,字符串多个用空格分隔,数组可以由字符或对象组成。
      • ng-bind:绑定
      • ng-include:引入模块,必须放在服务器下面,js本身是读取不了本地文件的
      • ....
    • 自定义指令:angularjs自定义指令就是HTML属性或者标签,这些指令都是以ng-作为前缀
      • 通过模块实例对象的directive()方法可以自定义指令
        App.directive('指令名',function(){
             return{
                restrict:'EM',
                template:'想要表达的模板',
                templateUrl:'引入外来模板的路径'
             }
           })
           <--directive:tag-->  注释
           E(Element)表示该指令是一个element; A(Attribute)表示该指令是attribute; 
           C(Class)表示该指令是class; M(Mark replace)表示该指令是注释,必须为true否则出不来
                   
  • 数据绑定
    • 单向绑定:
      • 将模型(model)数据绑定到视图(view)上
    • 双向绑定:
      • 模型向视图、视图向模型
    • 单项绑定:
      *注意*:ng-bind="表达式"  可以解析
              ng-bind-template='字符串'  不可以解析
              所以ng-bind后直接是name可以自己去解析,ng-bind-template后面是{{}},{{}}解析后的返回值再作为字符串给ng-bind-template
                 
      • {{}}和ng-bind指令来实现模型(model)数据向视图(view)的绑定
      • {{}}是ng-bind的另一种写法,优点:更简单 缺点:会有一瞬间的闪动,可以通过添加ng-cloak来解决此问题,原理:添加style样式,设为none等angular编译后在设为block
        • ng-bind-template='{{数据一}}{{数据二}}'可以绑定多个数据
      • ng-repeat='(key,value) in 数组名':通过迭代将数组或者对象显示到视图上
      • ng-switch on、ng-switch-when:组合使用对数据进行筛
      • ng-switch on='XXX':对XXX进行筛选
      • ng-switch-when='XXX':只有满足XXX是才...
        <li ng-repeat='item in items' ng-switch="item">
            <span ng-switch-when="css">{{item}}</span>
        </li>
                   
    • 双向绑定:
      <body ng-app='App'>
         <div ng-controller="DemoController">
              <input type="text" ng-model="msg">
              <button ng-click="show()">显示</button>
         </div>
          <script src="js/angular.js"></script>
          <script>
          var App = angular.module("App",[]);
          App.controller("DemoController",["$scope",function($scope){
              $scope.show = function(){
                  alert($scope.msg);
              }
          }]);
          </script>
        </body>
                 
      • 要实现数据从视图向模型传递需要借助于表单元素,在表单元素上面添加一个指令ng-model=' '即:通过为表单元素添加**ng-model**指令实现视图模板向模型数据的绑定
  • 作用域:
    • js的作用域:
      • 新创建一个函数就会产生一个新的作用域,并且子作用域可以访问父级作用域,父级作用域不能访问子级作用域
    • angularjs作用域:
      • 新创建一个控制器就会产生一个新的作用域,并且子作用域可以访问父级作用域,父级作用域不能访问子级作用域
    • 根作用域
      • 相当于原始js里面的全局作用域(window),angularjs中ng-app下面的是全局作用域
  • 过滤器: 格式化展示数据
    • 内置过滤器
      {{num|number}}默认保留三位小数,可以通过传参来设置保留几位小数
                 
      • 使用方式: | 是调用过滤器 : 是传参
      • currency:将数值格式华为货币格式
        {{price|currency}}
        {{price|currency:'¥'}}:通过传参的形式改变符号
        ​
                   
      • date:日期格式化
        参数:yyyy-->四位年份  MM-->月份  dd-->日
        yyyy-MM-dd hh:mm:ss
                   
      • filter:在给定数组中选择满足条件的一个子集,并返回一个新数组,其条件可以是一个字符串、对象、函数
        {{items|filter:'s'}}:过滤数组中包含‘s’的子集
         {{students|filter:{age:18} }}:条件是对象
                   
        json:
        {{students|json}}:将数组转换为josn数据
                   
        limitTo:截取字符串、数组
        {{items|limitTo:2}}:截取字符串前两个字符、截取数组
                   
        前两个子集
        {{items|limitTo:正数}}:从左边开始截取  
              {{items|limitTo:负数}}:从右边开始截取
                   
      • uppercase:变成大写
      • lowercase:变成小写

        number:转换为数字,四舍五入

      • orderBy:对数组进行排序,第二个参数可控制方向
        {{items|orderBy:'':true}}:进行倒/降序
              {{items|orderBy:'':false}}:进行正/升序,默认为false
                   
      • 课外:parseInt与number的区别
        • parseInt:从首位查找一直查到不是数字

          如:10ad:10 10.12:10 ads10:Nan

        • number:不能有非数字

          如:10ad:NaN 12.12:12.12

    • 自定义过滤器
      • 通过filter()来自定义过滤器
        • 自定义一个首字母大写的过滤器:capitalize
          App.filter('capitalize', function(){
              //{{info|capitalize}}  因为使用管道即info的值传递capitalize函数当参数使用,所以需要接收参数,又因为需要把数值展示出来,所以里面的一个函数还需要return来返回值
              return function(input){ 
              //这里return function(input):可扩展性强,外面函数调用里面函数返回,否则会出错 
                 return input[0].toUpperCase() + input.slice(1); 
              }
           });
                     
  • 三个自定义
    • controller:自定义控制器
    • directive:自定义指令
    • filter:自定义过滤器
  • 依赖注入
    • 在使用angularjs进行开发时,需要用angularjs事情先提供的模块,开发自己的业务逻辑例如造一个控制器,需要有一个模块2(模型),这是开发需要小angularjs申请需要的模块2,angularjs会主动去查找有没有一个模块2,找到后再交给开发者,交给的过程成为注入。即告诉angularjs自己依赖于那个模块,angular去找,找到后以注入的方式传递给自己App.controller('DemoController',['$scope',function(参数名称){}]:[]中就是依赖注入,需要$scope模块,angularjs以传参的形式注入给我,参数名称可以随意 可以理解为依赖传参
    • 行内式注入:

      App.controller('DemoController',['$scope',function(参数名称){}] 可以依赖多个模块,并列写,有几个模块传几个参数,最好参数名称和模块名称相同,防止多个参数混淆

    • 推断式依赖注入:App.controller('DemoController',function($scope){});此时参数名称不能乱写,必须要正确,符号也不能省略,因为​表示angular内置的意思,是angular自己定义好的
    • 现实开发中一般不使用推断式依赖注入,因为代码写完后要进行压缩,参数被压缩后会改变成简单的,最终会因为参数名改变而出错
  • 服务:是一个对象或函数,对外提供特定的功能
    • 内建服务:
      • $location模块是对原生js中的location对象属性和方法的封装,为了获取地址信息
        • 从锚点开始往后都是属于url()的信息
        • absUrl()获取完整路径 url() host() search()
        • hash()锚点:angularjs中的锚点认定是在js认定的锚点中再找#号,有的话才是锚点 protocol()协议 port()端口
        • 地址是由若干部分组合成的:
          • http:协议 host:www.baidu.com/127.0.0.1:主机 port:端口号 hash:锚点 serch:?name=itcase&age=10:查询参数数据
      • $filter模块:
        • $filter():代表了所有的过滤器,可以通过传参数的方式来使用过滤器
          $scope.str = 'hello angular';
          var uppercase = $filter('uppercase');
          $scope.str = uppercase($scope.str);
          合并写为:$scope.str1 = 'hello javascript';
                   $scope.str1 = $filter('uppercase')($scope.str1);
                     
      • $log模块:日志服务 $log.info() warn() error() log() debug()
      • $http模块:ajax params{}里面的内容会自动拼接在url后面
    • 自定义服务:依赖于$filter, 提供了三种方法实现自定义服务:factory、service、value
      • factory:
        App.factory('format', ['filter', function(filter){return function (arg){};}]);
                   
      • srvice:
        this.函数名 = function(){} === return {函数名:function(){}}
        ​
        var App = angular.module('App', []);               
            App.controller('DemoController', ['scope','showTime', function(scope,showTime){ 
                $scope.now = showTime.now();             
            }]);        |      |                         
                       服务名 函数名             
            App.service('showTime',['filter',function(filter){                       
                var now = new Date;                                                         
                var date = $filter('date');               
                this.now = function(){                                                     
                    return date(now,'yyyy-MM-dd hh:mm:ss');                                 
                }                                         
            }]);                              
                   
      • value:功能单一 本质上是一个服务,但是表现形式上看,更像一个系统常量
        App.controller('DemoController', ['scope','author','version', function(scope,author,version){       
            $scope.author = author;
            $scope.version = version;
               }]);
               App.value('author', '朱一龙');
               App.value('version', '1.0');
                   
      • ajax补充:XMLHttpRequest对象,具备向服务端发送请求和接收响应的一个能力
        var xhr = new XMLHttpRequest;  xhr.open('get/post','url');
        post请求时,由于数据是放到请求主体里的,所以必须要设置请求头(xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');)。get请求的时候没有请求主体,所以不用设置,即send()/send(null)。  请求主体就是请求的数据
         xhr.send();    
         xhr.onreadystatechange = function(){}
                   
  • 跨域限制:
    • 标签的src和href属性没有跨域限制
    • ajax的$http:
      $http({
           url:'请求地址',
           type:'请求方式',
           data:'传递的参数 name=itcase&age=10',
           success:function(data){data返回的数据}
       });
                 
    • angular的$http:
      params{}里面的内容会自动拼接在url后面
          $http({
            url:'请求地址',
            method:'请求方式 jsonp',
            headers:{请求头},
            data:{post传递的数据},
            params:{get请求的数据 call:'JSON_CALLBACK}--->回调函数,固定死的
           }).success(function(返回的数据){});
      ​
                 
  • 模块加载:在代码中,一个服务就是一个模块
      App.config(['filterProvider',function(filterProvider) {      
        $filterProvider.register('capitalize',function(){
           return function(input) {
            return input[0].toUpperCase() + input.slice(1);
           }
           });
               
    • 配置块:通过config来配置服务,angular中服务大部分都对应一个“provider”,用来执行与对应服务相同的功能或对其进行配置。如$log对应的是$logProvider....新增一个过滤器:
    • 运行块:直接运行$http、$rootScope服务
      App.run(['http','rootScope', function(http,rootScope){
          $http({
            url:'example.php',
            method:'get',
           }).success(function(info){
               console.log(info);
           });
               $rootScope.name = '朱一龙'; //如果在controller中又定义了name则会覆盖这个
         }]);
                 
  • 路由
    • SPA:单页面应用,若干个功能集中到一个页面,不产生跳转。动态产生数据,通过ajax异步获取。 增强了用户体验,可以提高性能
    • 锚点是前端的路由功能
    • hashchange事件可以监听锚点变化
      window.addEventListener('hashchange',function(){var hash = location.hash;//获取锚点 ...}
         $routeProvider.when('/index',{template: '<h1>Index Page!</h1>'})
          第一个参数是条件,第二个参数是一个对象,配置当前路由的参数、如视图、控制等
          template:字符串形式的视图模板
          templateUrl:引入外部视图模板
          controller:视图模板所属于的控制器
          redirectTo:跳转到其他路由
                 
    • 路由参数:
      • $routeParams服务传递参数 == ?号传参
      • 通过传参的方式:
        href="#/index/5" target="_blank" rel="external nofollow"  -->实参
        when('/index/:形参名')
                   
  • 转换:
    • angular.element() 方法可以讲一个原生DOM对象转成jQuery对象
      • 但是angularJS只能实现jQuery对象的部分方法 ,即angular‘s jqLite
      • 如果页面中引入了jQuery文件,那么不能实现的一部分也能实现了,即全部功能都实现
    • $()将原生dom随想转化为jQuery对象
  • bower:用来管理静态资源的工具 即用来下载插件的
    • 使用nodejs开发的,要想使用bower,需要先安装nodejs,nodejs就是一个软件,正常安装即可(下一步下一步)。
    • 在git窗口中:
      • bower install 想要下载的文件名称
      • bower info 文件名称 查看信息
      • bower uninstall 文件名称 卸载
      • bower search 关键字 查找信息
    • 可以自动解决依赖:如果再安装一个文件A,此文件A有依赖前提时,bower会自动将所依赖的文件B也给下载下来,且卸载的时候只能卸载文件A不能直接卸载文件B
  • 使用angularjs写项目:(可忽略)
    • 目录结构: 为了方便管理,统一建立模块、过滤器、指令来管理下面的模块...
    • PHP中strtotime()函数可以回到过去的时间。$today = strtotime('-1day', time());-->回到当前时间的前一天
    • 大写M:表示月份的三个缩写字母,小写m表示月份的数字带前导0....
  • Gulp
    • 本地(项目)安装gulp
    • 项目构建,构建任务清单gulpfile.js文件
    • gulp插件:在gulpfile.js文件书写下列内容:
      所有插件是用的前提都是要先使用require('插件名');命令引入进来,引入后都是函数
       -npm install gulp-less  将less文件转成css文件
         使用方法:首先引入本地安装的gulp与gulp-less
               然后:gulp.task('test',function(){           
                  return gulp.src('./public/less/.less')// 借助gulp.src来制定less的文件位置,通俗地讲就是‘去哪拿’  当想要拿到文件夹中的文件夹里的内容是可以使用两个
                  // 借助gulp插件实现less转css的操作
                  .pipe(less())
                  .pipe(cssmin())       
                  .pipe(gulp.dest('./release/public'));// 通过gulp.dest进行存储
                  });
                最后:gulp zr执行  return:为了保证同步执行
                 
  • Gulp插件:
    • npm install gulp-cssmin 将css文件压缩
    • npm install gulp-imagemin 图片压缩
    • npm install gulp-uglify 压缩JavaScript
    • npm install gulp-concat 合并(js的任务,可以先合并后压缩,由于多个文件合并为一个文件所以需要重新取名字:.pipe(concat('all.js')).pipe(uglify())... ) 只合并,路径不改
    • npm install htmlmin 压缩HTML文件
      .pipe(htmlmin{collapseWhitespace: true})合并空白处
      gulp.src(['./index.html','./views/*.html'],{base:'./'}).pipe(dulp.dest('./release'))-->代表着./不动,index.html直接放到./release下面,而后面一个是放到./releaseviews/下面
                 
    • npm install gulp-autoprefixer 添加css私有前缀
    • npm install gulp-rname 重命名
    • npm install gulp-rev 添加版本号
      .pipe(rev()).pipe(gulp.dest('...')).pipe(rev.manifest()).pipe(gulp.dest('...'))-->添加版本号(即改为加密的名字)后需要先存好然后再通过rev.manifest()方法找rev()方法操作的文件,将对应关系收集(记录把原始名字改成的新名字)起来放到另一个存储地
                 
    • npm install gulp-rev-collector 内容替换
      gulp.src(['替换内容','被替换内容']).pipe().pipe(gulp.dest())
       替换内容是rev.manifest()收集的新旧名称对应关系,将被替换内容里面的旧名称换成新的
                 
    • npm install gulp-useref 合并文件不压缩 路径改变
      合并的文件需要使用注释标记一下:<!-- bulid:xxx ./main.yyy(路径)--><!-- endbulid -->
                                     ./main.yyy--:更改的路径文件
        pipe(useref()).pipe(gulpif('*.js', uglify() )) -->如果是js文件就丑化压缩一下
      ​
        gulp-useref:也支持删除
        <!--bulid:remove--<!--endbulid-->
                 
    • npm install gulp-if
    • 总结:由于项目都是按文件夹分好类的,所以可以单纯的认为一个文件夹可以定义一个任务gulp.src([])中可以放数组已达到能够写多个不同地址的文件
  • npm init 创建package.json文件记录我们的配置信息
  • --svae-dev 与 --save的区别:
    --save 会把依赖包名称添加到 package.json 文件 dependencies 键下,
     --save-dev 则添加到 package.json 文件 devDependencies 键下  会在package.json记录依赖关系
      据npm文档所说dependencies是运行时依赖,即dependencies 下的模块,是我们发布后还需要依赖的模块,如jQuery库或者Angular框架类似的,我们在开发完后后肯定还要依赖它们,否则就运行不了。
      devDependencies是开发时的依赖,即devDependencies 下列出的模块,是我们开发时用的,
      比如 我们安装 js的压缩包gulp-uglify 时,我们采用的是 “npm install –save-dev gulp-uglify ”命令安装,因为我们在发布后用不到它,而只是在我们开发才用到它。
    
    
               
  • 一次性运行:
    最后可以在定义一个任务来依赖其他的任务已达到一次性执行:gulp.task('all',['zr','image','...'],function(){console.log('全部完成!')});
    或gulp.task('all',['zr','image','...']);