zoukankan      html  css  js  c++  java
  • Angular(一)

    一、Angular优点:

    1、MVC:职责清晰,代码模块化。

    2、模块化

    3、指定系统——directive:我们已经在模板中看到了一些新的属性,这些属性不属于HTML规范。例如:我们引入了双花括号用来实现数据绑定;引入了ng-controller用来指定每个控制器负责监视视图中的哪一部分;引入ng-model,用来把输入数据绑定到模型中的一部分属性上。我们把这些指令叫做HTML扩展指令。

    4、双向数据绑定

    5、依赖注入:进行数据绑定的$scope对象会被自动传递给我们;我们并不需要调用任何函数去创建这个对象。只要把$scope对象放在控制器的构造函数里面,然后就可以获取它了。并且$scope并不是我们唯一可以获取的东西。如果我们想把数据绑定到用户浏览器中的URL地址上,可以使用$location对象,只要把$location对象放到我们的构造函数中即可,例如:

    function HelloCtroller($scope,$location) {
        $scope.greeting={text:'Hello'};
      //这里可以使用$location对象来做一些很酷的事儿 }

    这种神奇的效果是通过angular的依赖注入机制实现的。依赖注入让我们遵守这样一种开发风格:我们的类只是简单获取它们所需要的东西,而不需要创建那些它们所依赖的东西。

     二、Model View Controller

    <!DOCTYPE html>
    <html lang="en" ng-app='myApp'>
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body ng-controller='TextController'>
        <p>{{someText.message}}</p>
        <script src='angular-1.3.0.js'></script>
        <script>
            var myApp=angular.module('myApp',[]);
            myApp.controller("TextController",["$scope",function($scope){
                var someText={};
                someText.message='hahhaha';
                $scope.someText=someText;
             }]);
        </script>
    </body>
    </html>

    其中,<p>{{someText.message}}</p> 采用双花括号插值语法,把新的内容插入到现有的模板中。

    控制器就是你所编写的类或者类型,它的作用是告诉Angular该模型是由哪些对象或者基本数据构成的,只要把这些队形或者基本数据设置到$scope对象上即可,$scope对象会被传递给控制器。

    通过$scope对象把数据模型和函数暴露给视图(UI模板)。

    这个版本中,我们把ng-app属性设置成了模块的名称myApp。然后我们再调用angular对象创建了一个名为myApp的模块,并且把控制器函数传递给了myApp模块的controller函数。

    采用模块机制可以把东西从全局命名空间中隔离开。

    三、模块和数据绑定

    1、表单输入

    <!DOCTYPE html>
    <html lang="en" ng-app='myApp'>
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <form ng-controller = "SomeController">
            Starting:<input ng-change='computeNeeded()' ng-model="funding.startingEstimate">
            Recommendation:{{funding.needed}}
        </form>
        <script src='angular-1.3.0.js'></script>
        <script>
            var myApp=angular.module('myApp',[]);
            myApp.controller("SomeController",["$scope",function($scope){
                $scope.funding={startingEstimate:0};
                
                $scope.computeNeeded=function(){
                    $scope.funding.needed=$scope.funding.startingEstimate*10;
                }
             }]);
    
        </script>
    </body>
    </html>

    对于输入元素说,可以使用ng-change属性来指定一个控制器方法,一旦用户修改了输入元素,这个方法就会被调用。

    当用户在这个特定的输入框中输入时,输入框就会正确地刷新。但是,如果还有其他输入框也绑定到模型中的这个属性上,会怎么样呢?如果接受到服务器的数据,导致数据模型进行刷新,又会怎样?

    为了能够正确地刷新输入框,而不管他是通过何种途径进行刷新的,我们需要使用$scope中的$watch函数。最基本的一点就是,可以调用$watch()函数来监视一个表达式,当这个表达式发生变化时就会调用一个回调函数。

    <!DOCTYPE html>
    <html lang="en" ng-app='myApp'>
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body>
        <form ng-controller = "SomeController">
            Starting:<input ng-model="funding.startingEstimate">
            Recommendation:{{funding.needed}}
        </form>
        <script src='angular-1.3.0.js'></script>
        <script>
            var myApp=angular.module('myApp',[]);
            myApp.controller("SomeController",["$scope",function($scope){
                $scope.funding={startingEstimate:0};
                computeNeeded=function(){
                    $scope.funding.needed=$scope.funding.startingEstimate*10;
                    console.log($scope.funding.startingEstimate);
                };
                $scope.$watch('funding.startingEstimate',computeNeeded)
             }]);
    
        </script>
    </body>
    </html>

    请注意,$scope.$watch('funding.startingEstimate',computeNeeded) 需要监视的表达式位于引号中,它是一个字符串。这个字符串会被当做angular表达式来执行。当他的值发生变化时,就调用computeNeeded()。

    2、列表、表格以及其他迭代型元素

    <!DOCTYPE html>
    <html lang="en" ng-app='myApp'>
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body ng-controller='TextController'>
        <ul>
            <li ng-repeat='student in students'>
                <a href="/student/view/{{student.id}}">{{student.name}}</a>
            </li>
        </ul>
        <button ng-click='insertTom()'>Insert</button>
        <script src='angular-1.3.0.js'></script>
        <script>
            var myApp=angular.module('myApp',[]);
            var students=[{name:'Mary',id:'1'},{name:'Jack',id:'2'},{name:'Jill',id:'3'}];
            myApp.controller("TextController",["$scope",function($scope){
                $scope.students=students;
                $scope.insertTom=function(){
                    $scope.students.splice(1,0,{name:'Tom',id:'4'})
                }
             }]);
        </script>
    </body>
    </html>

    ng-repeat指令可以通过$index返回当前引用的元素序号;还可以通过$first、$middle、$last,ng-repeat指令返回布尔值,告诉你当前元素是否是集合中的第一个元素、中间的某个元素,或者最后一个元素。

    3、隐藏和显示/CSS类和样式

    <!DOCTYPE html>
    <html lang="en" ng-app='myApp'>
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
            .menu-disabled-true{background:gray;}
        </style>
    </head>
    <body ng-controller='TextController'>
        <button ng-click='toggleMenu()'>Toggle Menu</button>
        <ul ng-show='menuState'>
            <li class='menu-disabled-{{isDisabled}}' ng-click="stun()">stun</li>
            <li ng-click="disintegrate()">disintegrate</li>
            <li ng-click="erase()">erase from history</li>
        </ul>
        <script src='angular-1.3.0.js'></script>
        <script>
            var myApp=angular.module('myApp',[]);    
            myApp.controller("TextController",["$scope",function($scope){
                $scope.menuState=true;
                $scope.isDisabled=false;
                $scope.toggleMenu=function(){
                    $scope.menuState= !$scope.menuState;
                }
                $scope.stun=function(){
                    $scope.isDisabled=true;
                }
    
             }]);
        </script>
    </body>
    </html>

    现在可以动态的设置css类和样式了,只要使用{{}}插值语法把它们进行数据绑定即可。

    4、ng-class、ng-style

    <!DOCTYPE html>
    <html lang="en" ng-app='myApp'>
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
            .error{
                background: red;
            }
            .warning{
                background: yellow;
            }
        </style>
    </head>
    <body ng-controller='TextController'>
        <div ng-class="{error:isError,warning:isWarning}">
            {{messageTxt}}
        </div>
        <button ng-click="showError()">Simulate Error</button>
        <button ng-click="showWarning()">Simulate Warning</button>
    
        <script src='angular-1.3.0.js'></script>
        <script>
            var myApp=angular.module('myApp',[]);
            myApp.controller("TextController",["$scope",function($scope){
                $scope.isError=false;
                $scope.isWarning=false;
    
                $scope.showError=function(){
                    $scope.messageTxt='This is an error';
                    $scope.isError=true;
                    $scope.isWarning=false;
                };
                $scope.showWarning=function(){
                    $scope.messageTxt='Just a warning.Please carry on.';
                    $scope.isWarning=true;
                    $scope.isError=false;
                }
             }]);
    
        </script>
    </body>
    </html>

    若需要将表格中被选中的行进行高亮显示:

    <!DOCTYPE html>
    <html lang="en" ng-app='myApp'>
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
        <style>
            .selected{background: lightgreen;}
        </style>
    </head>
    <body ng-controller='TextController'>
        <table>
            <tr ng-repeat='student in students' ng-click='select($index)' ng-class='{selected:$index==selectedRow}'>
                <td>{{student.id}}</td>
                <td>{{student.name}}</td>
            </tr>
        </table>
        <script src='angular-1.3.0.js'></script>
        <script>
            var myApp=angular.module('myApp',[]);
            var students=[{name:'Mary',id:'1'},{name:'Jack',id:'2'},{name:'Jill',id:'3'}];
            myApp.controller("TextController",["$scope",function($scope){
                $scope.students=students;
    $scope.select
    =function(row){ $scope.selectedRow=row; } }]); </script> </body> </html>

    在上面中,我们把ng-class设置为{selected:$index==selectRow}。这样做的效果就是,当模型属性selectRow的值等于ng-repeat中的$index时,selected样式就会被设置到那一行上。而ng-click则是告诉控制器用户点击了哪一行。

    5、使用$watch 监控数据模型的变化

    当你的数据模型中某一部分发生变化时,$watch函数可以向你发出通知。你可以监控单个对象的属性,也可以监控需要经过计算的结果(函数),实际上只要能够被当作属性访问到,或者可以当做一个Javascript函数被计算出来,就可以被$watch函数监控。它的函数签名为:$watch(watchFn,watchAction,deepWatch);

    $watch函数会返回一个函数,当你不再需要接收变更通知时,可以用这个返回的函数注销监控器。

     将(二)中的购物车功能进行扩充完整。例如,当用户添加到购物车中的商品价值超过100美元时,我们会给他10美元的折扣。如下:

     1 <!DOCTYPE html>
     2 <html lang="en" ng-app='myApp'>
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>Document</title>
     6 </head>
     7 <body ng-controller='CartController'>
     8     <h1>Your Order</h1>
     9     <div ng-repeat='item in items'>
    10         <span>{{item.title}}</span>
    11         <input type="text" ng-model='item.quality'>
    12         <span>{{item.price|currency}}</span>
    13         <span>{{item.price*item.quality|currency}}</span>
    14         <button ng-click='remove($index)'>Remove</button>
    15     </div>
    16     <div>total:{{totalCart()|currency}}</div>
    17     <div>discount:{{bill.discount|currency}}</div>
    18     <div>subtotal:{{subtotal()|currency}}</div>
    19     <script src='angular-1.3.0.js'></script>
    20     <script>
    21         var myApp=angular.module('myApp',[]);
    22         myApp.controller("CartController",["$scope",function($scope){
    23             $scope.bill={};
    24              $scope.items=[
    25                 {title:'Paint pots',quality:8,price:3.95},
    26                 {title:'Polka dots',quality:17,price:12.95},
    27                 {title:'Pebbles',quality:5,price:6.95}
    28             ];
    29             $scope.totalCart=function(){
    30                 var total=0;
    31                 for (var i = 0,len = $scope.items.length; i<len;i++) {
    32                     total=total+$scope.items[i].price*$scope.items[i].quality;
    33                 }
    34                 return total;
    35             }
    36             $scope.subtotal=function(){
    37                 return $scope.totalCart()-$scope.bill.discount;        
    38             }
    39             function calculateDiscount(newValue,oldValue,scope){
    40                 $scope.bill.discount=newValue>100?10:0;
    41             }
    42             $scope.$watch($scope.totalCart,calculateDiscount);
    43             $scope.remove=function(index){
    44                 console.log(index);
    45                 $scope.items.splice(index,1)
    46             }
    47 
    48          }]);        
    49     </script>
    50 </body>
    51 </html>

    另:watch中的性能注意事项:

    上个例子可以正确地运行,但是却潜在性能问题。如果你在totalCart()中打个调试断点,你会发现在渲染这个页面时,该函数被调用了6次。虽然在当前这个应用中它所引起的性能问题并不明显,但是在更加复杂的应用中,运行6次就会成为一个问题。

    为什么是6次呢?其中3次我们可以很容易跟踪到,因为在以下每种情况下,它都会运行一次:

    • 模板{{totalCart()|currency}}
    • subtotal()函数
    • $watch()函数

    然后angular把以上整个过程又重复了一遍,最终是6次。angular这样做的目的是,检测模型中的变更已经被完整地进行了传播,并且模型已经被设置好。angular的做法是,把所有被监控的属性都拷贝一份,然后把它们和当前的值进行比较,看看是否发生了变化。

    有几种方法可以解决这个问题。一种方法是监控items数组的变化,然后重新计算$scope属性中的总价、折扣和小计值。

    <!DOCTYPE html>
    <html lang="en" ng-app='myApp'>
    <head>
        <meta charset="UTF-8">
        <title>Document</title>
    </head>
    <body ng-controller='CartController'>
        <h1>Your Order</h1>
        <div ng-repeat='item in items'>
            <span>{{item.title}}</span>
            <input type="text" ng-model='item.quality'>
            <span>{{item.price|currency}}</span>
            <span>{{item.price*item.quality|currency}}</span>
            <button ng-click='remove($index)'>Remove</button>
        </div>
        <div>total:{{bill.totalCart|currency}}</div>
        <div>discount:{{bill.discount|currency}}</div>
        <div>subtotal:{{bill.subtotal|currency}}</div>
        <script src='angular-1.3.0.js'></script>
        <script>
            var myApp=angular.module('myApp',[]);
            myApp.controller("CartController",["$scope",function($scope){
                $scope.bill={};
                 $scope.items=[
                    {title:'Paint pots',quality:8,price:3.95},
                    {title:'Polka dots',quality:17,price:12.95},
                    {title:'Pebbles',quality:5,price:6.95}
                ];
                $scope.calculateTotals=function(){
                    var total=0;
                    for (var i = 0,len = $scope.items.length; i<len;i++) {
                        total=total+$scope.items[i].price*$scope.items[i].quality;
                    }
                    $scope.bill.totalCart=total;
                    $scope.bill.discount=total>100?10:0;
                    $scope.bill.subtotal=total-$scope.bill.discount;
                };        
                $scope.$watch("items",$scope.calculateTotals,true);//此处第三个参数传递了一个true,请求angular遍历items的属性,
                                          当其中任何一个属性变化时就调用$scope函数 $scope.remove
    =function(index){ console.log(index); $scope.items.splice(index,1) } }]); </script> </body> </html>

    请注意,上面的代码在调用$watch函数时把items写成了一个字符串。这样做是可以的,因为$watch函数既可以接受一个函数(就像我们之前说的),也可以接受一个字符串。如果把一个字符串传递给了$watch函数,它将会在被调用的$watch作用域中当成表达式来执行。

    对于这种应用来说,这种策略可能会工作得很好。但是,既然我们在监控items数组,angular就会制作一份数组的拷贝,用来进行比较操作。对于大型的items数组来说,如果每次在angular显示页面时只需要重新计算bill属性,那么性能会好很多。

    可以通过创建一个带有watchFn的$watch函数我们就可以实现这一点,watchFn将会像下面这样来重新计算属性值:

            myApp.controller("CartController",["$scope",function($scope){
                $scope.bill={};
                 $scope.items=[
                    {title:'Paint pots',quality:8,price:3.95},
                    {title:'Polka dots',quality:17,price:12.95},
                    {title:'Pebbles',quality:5,price:6.95}
                ];
                $scope.$watch(function(){
                    var total=0;
                    for (var i = 0,len = $scope.items.length; i<len;i++) {
                        total=total+$scope.items[i].price*$scope.items[i].quality;
                    }
                    $scope.bill.totalCart=total;
                    $scope.bill.discount=total>100?10:0;
                    $scope.bill.subtotal=total-$scope.bill.discount;
                })
            
                $scope.remove=function(index){
                    console.log(index);
                    $scope.items.splice(index,1)
                }
             }]);
    努力将自己的温暖带给身边的人!!!!!
  • 相关阅读:
    easy ui 表单ajax和from两种提交数据方法
    easy ui 下拉级联效果 ,下拉框绑定数据select控件
    easy ui 下拉框绑定数据select控件
    easy ui 异步上传文件,跨域
    easy ui 菜单和按钮(Menu and Button)
    HTTP 错误 404.3
    EXTJS4.2 后台管理菜单栏
    HTML 背景图片自适应
    easy ui 表单元素input控件后面加说明(红色)
    EXTJS 4.2 添加滚动条
  • 原文地址:https://www.cnblogs.com/xiaoli52qd/p/6479352.html
Copyright © 2011-2022 走看看