Angular教程

原创 827538259 教程 流行框架angular 829阅读 2017-06-22 19:17:59 举报

Angular简介

  • 可以轻松构建 SPA 应用程序
  • 其核心是通过指令扩展了HTML , 通过表达式绑定数据到HTML

########什么是 SPA

  • single page application
  • 单页应用程序

Angular教程

    //1.监听url中锚点值变化的事件 hashchange
    window.addEventListener("hashchange",function(){
        //2.根据不同的锚点值请求不同的数据
        // var url = location.href;
        var hash = location.hash;
    })

########指令

  • 在angular中以ng-开头的html标签属性,称之为指令
  • ng-app 选择angular去管理那一部分的html代码,管理的是ng-app所在元素的子元素及其本身
  • ng-click: 注册点击事件
  • ng-model: 可以指定一个属性值,这个属性值就表示当前文本框的value值
  • ng-init 可以对数据进行初始化操作,给一个默认值。

########工作原理

Angular教程

########angular模块

  • var win = angular.module("模块名",["win","stack"]);
    • 我们自己提供一个模块, 去管理页面
    • 第一个参数是模块的名字
    • 若当前模块需要依赖其他模块,就指定第二个参数为数组,
    • 数组中的元素就是我们当前模块依赖的模块
  • var win = angular.module("模块名",[ ]) ;
    • 若窗户不依赖于其他模块,也必须传入一个空数组
    • 若不传递第二个参数,就会变成获取窗户模块
      • var temp = angular.module("模块名")
  • 需要在ng-app指令的属性值上写上我们的模块名
    • <div ng-app="myWin"></div>

########控制器

  • 创建控制器
    • ‘win.controller('控制器的名字',function($scope){ })’
          win.controller("demoController",function($scope){
      //初始化数据模型
      $scope.testName = "小明";
      $scope.XXX = "小红";
        })
    • 如果要改变页面{{ testName }} 的值,就直接改变$scope(对象).testName值就可以
      + *注* 要显示数据模型的值,就要在他所在标签或者父标签上加上ng-controller指令
            ng-controller的值就是我们想要显示的数据模型所在的控制器的名字
         + ng-controller="demoController"

########双向数据绑定

  • 数据模型($scope.属性)的改变,会影响内容的显示(文本框的值)
  • 我们改变了文本框的值,对应的数据模型发生了改变
  • 这种相互影响的关系就称之为双向数据绑定

########MVC 思想

  • M : Model 存储 获取数据
  • V : View 视图 把数据呈现给用户
  • C : Controller 做一些控制和调度的操作
  • MVC只是一种思想-,只是约定了我们的代码如何去组织
  • 让我们代码的每一部分都有一个明确的职责
  • 有利于后期的维护性( 并不是提高了代码的执行性能,有可能10行代码放到10个方法中,10个方法再放到10个文件中 )

ViewModel

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

########Angular VS jQuery

  • jq 提高了dom操作的效率
  • angular 不推崇dom操作
  • angular.element, 使用方法和jquery非常像,jqLite对象
    • 在获取页面元素时,要求给一个原生的dom对象
      • 例如 :
        angular.element(document).ready(function(){
        var jqLiteDiv = angular.element(document.getElementById("box"));
        })

######## 回顾并总结Angular开发流程

  • 1.在html中引入angular.js文件
  • 2.在html中加上ng-app指令,告诉angular要管理页面哪一部分代码
  • 3.在js中创建模块angular.module('myApp',[]),给ng-app指令一个值,
  • 这个值就是这个模块的模块名:myApp
  • 4.在js中创建控制器xxx.controller('控制器名字',function($scope){}),我们需要在页面上加上ng-controller指令,指令的值为控制器的名字
    ng-controller="控制器名字"
  • 5.建模:根据页面结构,抽象出具体的js对象.
  • 6.通过$scope做一些初始化操作$scope.username="小明"
  • 7.通过ng-model , ng-click , {{}} 把$scope的属性在页面展示出来
  • 8.在js写一些具体的逻辑

######## Angular中模块的划分方式

  • 按照项目的功能去划分模块
  • 按照项目中文件的类型去划分模块

######## Angular中控制器的创建
### 传统方式创建控制器(1.2.x版本) -- angular会把全局的函数当做控制器
function demoController($scope){
$scope.name = " 小明 "
}

function xxx($scope){
$scop.age = 18;
}

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

######## 安全的方式创建控制器

  • 就是为了避免压缩后代码无法运行 代码压缩后function中的参数不是$scope 导致无法运行
  • 我们把第二个参数改为一个数组,把我们需要的参数的名字写上
  • 回调函数就写在数组的最后一个元素上
  • 数组中传入的元素的顺序 要和function中的顺序一一对应

app.controller("demoController" , ["$scope","$log",function($scope,$log){
$scope.msg = " hello World" ;
$log.log("哈哈哈 ")
}])

######## ng-bind 可以解决表达式闪烁的问题

  • 一般都把angular.js( 文件大 ) 放在html之后 先渲染{{msg}} 再加载angular.js 所以就会出现闪烁的问题
  • <div> {{ msg }} </div> (闪烁)
  • <div mg-bind="msg"></div> (不闪烁)
  • 浏览器不会把标签的属性显示出来
  • 效果 angular会把ng-bind 对应的数据显示到所在标签中间

######## ng-cloak 解决表达式闪烁的问题

  • <div class="ng-cloak">{{msg}}</div> .ng-cloak{ display:none;} 先隐藏后显示
  • angular在解析表达式之后会把页面上的ng-cloak 样式移除
    • 这样 ng-cloak 对应的样式就不生效了 我们就先设置 .ng-cloak{ display:none;}

######## ng-repeat

  • 能够把一组数据直接渲染到页面上,不需要我们拼接字符串
  • 我们希望重复的是哪个元素就把ng-repeat指令加在哪个元素上,不一定是li上
  • ng-repeat="item in users" , item对应是遍历users时的第一条数据,users是我们
  • 要遍历的数据(是一个数组)

########安装angularJS Batarang
安装文档

  • 需要在localhost环境下查看

Angular教程

########ng-repeat 补充

  • ng-repeat 在遍历时会提供以下值
    • $odd 为true时,表明当前数据是第奇数条
    • $even 为true时,表明当前数据是第偶数条
    • $first 为true时,表明当前数据是第一条
    • $last 为true时,表明当前数据是最后一条
    • $middle 为true时,表明当前数据是中间条

      <!--
      $odd ng-repeat在每次遍历的时候都提供这样的值,为true表明当前数据是奇数条,从索引为0开始判断的
      $even ng-repeat在每次遍历的时候都提供这样的值,为true表明当前数据是偶数条,从索引为0开始判断的

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

########ng-class

  • ng-class 可以帮我们控制元素的class样式
  • ng-class可以独立在其他元素上使用 并非一定要和ng-repeat结合
  • ng-class,动态的添加class样式, 以对象的形式书写,angular会把属性值为true的属性名当作样式添加到class
  • item用在ng-repeat所在标签
    <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-show/ng-hide

  • 控制元素的显示与否,ng-show与ng-hide作用是相反的(只是设置display:none来隐藏元素)

######## ng-if

  • 控制元素的显示与否 值为true时 显示
    值为false时 元素会从dom移除


<p ng-if="true">我是小明</p>
<p ng-if="false">我是小红</p>

######## ng-switch
<div ng-switch="name">
<div ng-switch-when="小明">我是小明</div>
<div ng-switch-when="小红">我是小红</div>
</div>

        $scope.name = "小红";
        switch($scope.name){
            case "小明":
               console.log("小明");
               break;
            case "小红":
                console.log("小红");
                break;
        }

######## 其他常用指令

  • ng-checked
    • 单选 / 复选 是否选中 它是单向数据绑定:界面操作不会影响数据模型的值
    • no-model:双向绑定数据
  • ng-selected:
    • 是否选中
  • ng-disabled:
    • 是否禁用
  • ng-readonly:
    • 是否只读

######## 常用事件指令

  • ng-blur:失去焦点
  • ng-focus: 获得焦点
  • ng-change: 内容改变
  • ng-copy: 复制
  • ng-click
  • ng-dbclick 双击
  • ng-submit form表单提交

######## 指令的其他使用方式

  • data-xxx 在使用angular指令时,只需要在原先的指令前加上data-前缀
  • 如data-ng-app,data-ng-click
    x-ng-app , x-ng-click

####### 创建自定义指令

  • 注意: 名字要符合驼峰合法

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

  • template 需要提供一个html字符串,最终会被添加到当前页面使用了自定义指令的位置
    • return { template:"<div><button>我是按钮</button></div>" }
  • templateUrl 需要提供一个html文件路径,angular会发请求,请求对应的文件,把文件内容作为模板插入到自定义指令中间
    • return{ templateUrl:"01.template.html" }
    • 当页面加载时 可以看出这是异步加载出的文件

Angular教程

  • templateUrl 也可以提供一个script标签的id,angular会把script标签中的内容作为模板插入到自定义指令中间,/ 要改变script标签的type=“text/ng-template” /
    • return{ templateUrl:"tpl" }
      <script id="tpl" type="text/ng-template">
      <div>
      <button>我在javascript中</button>
      </div>
      </script>

      -restrict属性
    • angular指令的使用形式 A. 以属性的形式显示 ng-app B.以类名的形式显示 class="ng-cloak"
    • restrict 就是来限制自定义指令的使用形式
    • 需要提供一个字符串
      ++ A 表示指令只能以属性的形式使用
      ++ C 表示指令只能以类样式名的形式使用
      ++ E 表示指令只能以自定义标签的形式使用
      ++ ACE 多种方式都能使用
      <h1>以属性的形式显示 A</h1>
      <div my-btn></div>
      <h1>以类名的形式显示 C</h1>
      <div class="my-btn"></div>
      <h1>以自定义标签的形式显示 E</h1>
      <my-btn></my-btn>

      app.directive("myBtn",[function(){
      return {
      template:"<div><button>我是按钮</button></div>",
      //restrict:"A"
      // restrict:"C"
      // restrict:"E"
      restrict:"ECA" ,
      replace:true
      }
      }])

  • replace属性
    • 需要提供一个布尔值,为true时,模板会被用来替换自定义指令所在标签,而不是插入到自定义指令中间
  • transclude 属性
    • 需要提供一个布尔值,为true时,会将自定义标签中的内容插入到模板中 拥有ng-transclude指令的标签中间
  • scope 需要一个对象 可以用来获取自定义指令的属性值
    • 给当前对象添加一个属性(tmp), 属性值以@开头后面跟上自定义指令的属性名,然后就可以在模板中使用{{tmp}}来得到相应的 属性值
      • <my-btn mystyle="login">btnRed</my-btn>
        app.directive("myBtn",[function(){
        return {
        template:"<span><button ng-transclude class="{{tmp / mystyle}}">我是按钮</button></span>",
        restrict:"ECA" ,
        replace:true,
        transclude:true,
        scope:{
        // tmp:"@mystyle" //login
        mystyle:"@" //这是上一行的简写
        }
        }
        }])
  • link 需要一个function 这个function在angular解析到相应指令时就会执行一次
    • scope 类似于$scope 只不过scope的属性只能在模板中使用
    • element 自定义指令所在标签对应的对象(jqLight)
    • attribute包含了自定义指令所在标签的必有属性
      link:function(scope,element,attribute){
      //console.log("button"); //控制台输出3次“button”
      //参数:scope类似于控制器里的$scope
      //使用范围 $scope用在ng-controller包裹的代码内 scope是在模板中使用
      scope.msg = "我是中国人,我是小明";
      //参数:element 指向模板最外层的对象
      //console.log中查看对象 innerHTML <div class="ceshi"><p>我是中国人,我是小明</p><button>按钮</button></div>
      //若加上replace:true element指向的就是自定义指令所在标签
      //console.log中查看对象 innerHTML <p>我是中国人,我是小明</p><button>按钮</button>
      console.log(element);
      element.on("click",function(){
      alert("你点击我了");
      })
      console.log(attribute);
      }

########过滤器(filter)

  • 格式化数据
  • 过滤数据(filter)
    • 在数据模型后加 | 再加上过滤器的名字:“参数”
      <p>{{money | currency}}</p>
      <p>{{money | currency:"¥"}}</p>
      <p>{{myDate | date}}</p>
      <p>{{myDate | date:"yyyy-MM-dd HH:mm:ss"}}</p>
  • limitTo
    <!-- 第一个参数,表明显示多少个字,第二个参数表示,从第几个字开始显示(索引从0开始) -->
    <p>{{msg | limitTo : 5}}...</p>
    <p>{{msg | limitTo : 5 :2}}...</p>
  • orderBy
    <!--对数据进行排序,参数 给+号就按正序排 -号就按倒序排 -->
    <p><span ng-repeat="item in arr | orderBy : '+'">{{item}},</span></p>
    <p><span ng-repeat="item in arr | orderBy : '-'">{{item}},</span></p>

-json

  • / 注 :使用pre标签 结果: 分行缩进显示 而不是一行显示json数据/
    <h1>json</h1>
    <!--格式化显示json数据,参数指定缩进的长度 -->
    <pre>{{myJson | json : 8}}</pre>

在js中使用过滤器

app.controller("filterController",["$scope","$filter",function($scope,$filter){
$scope.money = 9998;
[color=#a5a5a5] // 可以调用不同的过滤器得到相应的结果
// 参数是一个过滤器的名字
// 返回值是一个方法
// : 第一个参数是需要处理的数据
// : 后面的参数是当前过滤器本身需要的参数

$scope.result = $filter('currency')($scope.money,'¥')
}])[/color]

  • {{ filter_expression | filter : expression }}
    • expression 从array选择条目时的条件 取值:
      • string array中包含这个字符串的所有字符串或字符串属性对象会返回
      • object {name:"M", phone:"1"} 表示返回数据组中属性name 包含 "M" 和属性 phone 包含 "1"的条目

$watch 监视数据模型的变化

         $scope.name = "小明";
         $scope.age = 18;

         $scope.getAge = function(){
            return $scope.age;
         }

                          //$watch可以用来监视数据模型的变化
         // 第一个参数: 数据模型对应的名字(字符串的形式)
         // 第二个参数: 相应的数据模型变化就会调用这个函数
         // 默认就会执行一次回调函数 所以 刷新页面 在控制台中可以看到123
         /*注:$watch监视的是$scope的属性.如果是普通变量或者普通方法是无法监视的  所以$scope.$watch("$location.url()")是错误的  */
         $scope.$watch("name",function(now,old){
            // 第一个参数是变化后的值 
            // 第二个参数是变化前的值
            console.log(123);
            console.log(now,old);
         }) 
  • 监视方法的返回值
    $scope.$watch("getAge()",function(now,old){
    console.log(now,old);
    })

#########服务

  • 创建服务
    (function(angular){
    // 1.创建服务模块
    var app = angular.module("service",[])
    // 2.创建服务
    // 第一个参数 服务的名字
    // 第二个参数里的function:
    // angular会把这个function当做构造函数,angular会帮助我们new这个构造函数,然后得到一个对象 A,B

    app.service("myService",[function(){
    this.name = "小明"
    }])

    })(angular)
  • 使用服务
    // myApp模块中的控制器要引用service模块中的服务
    var app = angular.module("myApp",["service"]);
    // myService是对应的myService回调函数new出来的对象
    app.controller("myController",["$scope","myService",function($scope,myService){
    console.log(myService); // Object {name: "小明"}
    }])

########路由

  • 根据url中不同的锚点值,在页面显示不同的内容
  • 在页面中需要引入 angular-route.js
    <div ng-view></div>
    var app = angular.module("myApp",["ngRoute"]);
    app.config(["$routeProvider",function($routeProvider){

    // 第一个参数 对应的url中的锚点值
    // 当angular检测到url中的锚点值变为/ali,就会把对应的template插入到页面拥有ng-view指令的标签中

    $routeProvider.when("/ali",{
    [color=#bfbfbf] template:"<div>阿里在二楼 {{msg}}</div>",
    // 指定一个控制器的名字
    // 当前url中锚点值为/ali时就会执行控制器中的回调函数
    // 我们可以直接在template/templateUrl对应的模板中使用该控制器中对应的$scope属性值

    controller:"demoController"
    })
    .when("/baidu",{
    template:"<div>百度在一楼</div>"
    })
    }])
    app.controller("demoController",["$scope",function($scope){
    $scope.msg = "我是中国人";
    }])
    [/color]

########路由参数
var app = angular.module("myApp",["ngRoute"]);
app.config(["$routeProvider",function($routeProvider){
[color=#a5a5a5] //在规则中以:号开始,后面跟一个名字(相当于是变量名,表明当前位置可以写成任意的值)
//***?表示当前位置如果没有值(myname为空),也可以匹配到

$routeProvider.when("/company/:myname?",{
template:"<div>别管我在几楼 {{msg}}</div>",
controller:"demoController"
})
.when("/xxx",{
template:"<div>哈哈哈</div>"
})
// 当以上规则都不匹配时,匹配otherwise里的规则
.otherwise({
// 这里相当于把页面锚点值改为company/ali
redirectTo:"/company/ali"
})
}])
app.controller("demoController",["$scope","$routeParams",function($scope,$routeParams){
// console.log($routeParams);
// $routeParams的属性包含了路由参数及值 object{ myname : "baidu" }

$scope.data = {
"baidu":"二楼",
"ali":"三楼",
"tx":"四楼"
}
$scope.msg = "你要找的公司在"+$scope.data[$routeParams.myname];
}])[/color]

########webapi

  • api
    • console.log("小明")
    • I / O 既有输入也有输出 的方法

########豆瓣api使用
https://developers.douban.com/wiki/?title=movie_v2#in_theaters 豆瓣开发者
http://api.douban.com/v2/movie/coming_soon 获取请求数据

-postman 安装
安装教程

-ng-src指令

  • 用来取代src
  • <img src=“{{ item.images.large }}” /> 当浏览器看到img src时就会去发请求,但是此时还没加载angular 所以不会识别{{}} 导致浏览器报404错误
  • 解决方案 <img ng-src=“{{ item.images.large }}” />

-跨域

  • 一个网站向另一个网站发请求 域名不同就会导致跨域(端口不同 协议不同)
  • 可以跨域请求的资源
    • img
    • link (css文件)
    • video audio
    • script (js文件)

A版本:

  • 假设tmp.js内容为 var data = 123
    <script src="b.com/tmp.js"></script>
    <script>
    console.log(data);
    </script>

B版本:

  • 假设tmp.js内容为 var data = {"name" : "小明",“age” : 18}
    <script src="b.com/tmp.js"></script>
    <script>
    console.log(data);
    </script>

C版本:

  • 假设tmp.js内容为 test(123)
    <script>
    function test(data){
    console.log(data);
    }
    </script>
    <script src="b.com/tmp.js"></script>

D版本:

  • 假设tmp.js内容为 test({"name" : "小明",“age” : 18})
    <script>
    function test(data){
    console.log(data);
    }
    </script>
    <script src="b.com/tmp.js"></script>
    / 原理:请求的js文件调用我们已经定义好的方法 /

-jsonp原理:
// 1.在创建标签之前写好我们的方法
function test(data){
console.log(data);
}

// 2.动态创建script
var scrp = document.createElement("script");
// 3.设置它的src属性 指向跨域文件
scrp.src = "./tmp.js?callback=test"
// 4.把标签添加到dom上
document.body.appendChild(scrp);

数组转字符串 arr.join("--")
字符串转数组 str.split(",") 将字符串按照某个字符(逗号)0进行分解,并返回一个数组
删除数组中的某一项 arr.splice(i,1);

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复