当前位置: 移动技术网 > IT编程>开发语言>JavaScript > AngularJS语法详解(续)

AngularJS语法详解(续)

2018年06月18日  | 移动技术网IT编程  | 我要评论

src和href属性

angularjs中src应写成ng-src,href应写成ng-href 例如:


<img ng-src="/images/cats/{{favoritecat}}">
<a ng-href="/shop/category={{number}}">some text</a>

表达式

在模板中可以进行简单的数学运算、比较运算、布尔运算、位运算、引用数组、和对象符号等 尽管我们可以使用表达式做很多事情,但是表达式是使用一个自定义的解释器来执行的(angular的一部分),而不是用javascript得eval()函数执行的,所以局限性较大。
虽然很多方面这里的表达式比javascript更严格,但是他们对undefined和null的容错性更好,如果遇到错误,模板只是简单的什么都不显示,而不会抛出一个nullpointerexception错误。 例如:


<div ng-controller='somecontroller'>
    <div>{{computer() /10 }}</div> //虽然是合法的,但是它把业务逻辑放到模板中了,应避免这种做法
</div>

区分ui和控制器的职责

控制器是绑定在特定dom片段上的,这些片段就是他们需要负责管理的内容。有两种主要的方法可以把控制器关联到dom节点上,一种在模板中通过ng-controller声明,第二种是通过路由把它绑定到一个动态加载的dom模板片段上,这个模板叫视图。 我们可以创建嵌套的控制器,他们可以通过继承数结构来共享数据模型和函数,真实的嵌套发生在$scope对象上,通过内部的原始继承机制,父控制器对象的$scope会被传递到内部嵌套的$scope(所有属性,包括函数)。例如:


<div ng-controller="parentcontroller">
    <div ng-controller="childcontroller">...</div>
</div>

利用$scope暴漏模型数据

可以显示创建$scope属性,例如$scope.count = 5。还可以间接的通过模板自身创建数据模型。

通过表达式。例如


<button ng-click='count=3'>set count to three</button>

在表单项上使用ng-model

与表达式类似,ng-model上指定的模型参数同样工作在外层控制器内。唯一的不同点在于,这样会在表单项和指定的模型之间建立双向绑定关系。

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

$watch的函数签名是: $watch(watchfn,watchaction,deepwatch)
watchfn是一个带有angular表达式或者函数的字符串,它会返回被监控的数据模型的当前值。 watchaction是一个函数或者表达式,当watchfn发生变化时调用。其函数签名为:
function(newvalue,oldvalue,scope) deepwatch 如果设置为true,这个可选的布尔值参数将会命令angular去检查被监控对象的每一个属性是否发生了变化。如果你向监控数组中的元素,或者对象上的所有属性,而不是值监控一个简单的值,你就可以使用这个参数。注意,angular需要遍历数组或者对象,如果集合比较大,那么运算复杂呢就会比较的重。

$watch函数会返回一个函数,当你不需要接收变更通知时,可以用这个返回的函数注销监控器。
如果我们需要监控一个属性,然后接着注销监控,我们就可以使用以下的代码: var dereg = $scope.$watch('somemodel.someproperty',callbackonchange());
... dereg();

实例代码如下:


<html ng-app>
<head>
    <title>your shopping cart</title>
    <script type="text/javascript">
        function cartcontroller($scope) {
            $scope.bill = {};
            $scope.items = [
                {title:'paint pots',quantity:8,price:3.95},
                {title:'polka dots',quantity:17,price:12.95},
                {title:'pebbles',quantity:5,price:6.95}
            ];
            $scope.totalcart = function() {
                var total = 0;
                for (var i=0,len=$scope.items.length;i<len;i++) {
                    total = total + $scope.items[i].price * $scope.items[i].quantity;
                }
                return total;
            }
            $scope.subtotal = function() {
                return $scope.totalcart() - $scope.bill.discount;
            }
            function calculatediscount(newvalue,oldvalue,scope) {
                $scope.bill.discount = newvalue > 100 ? 10 : 0;
            }//这里的watchaction函数
            $scope.$watch($scope.totalcart,calculatediscount);//这里的watch函数
        }
    </script>
</head>
<body>
    <div ng-controller="cartcontroller">
        <div ng-repeat='item in items'>
            <span>{{item.title}}</span>
            <input ng-model='item.quantity'>
            <span>{{item.price | currency}}</span>
            <span>{{item.price * item.quantity | currency}}</span>
        </div>
        <div>total: {{totalcart()| currency }}</div>
        <div>discount: {{bill.discount | currency}}</div>
        <div>subtotal: {{subtotal() | currency}}</div>
    </div>
    <script type="text/javascript" src="angular.min.js"></script>
</body>
</html>

上面的watch存在性能问题,calculatetotals函数执行了6次,其中三次是因为循坏,每次循环,都会重新渲染数据。
下面是改良后的代码


<html ng-app>
<head>
    <title>your shopping cart</title>
    <script type="text/javascript">
        function cartcontroller($scope) {
            $scope.bill = {};
            $scope.items = [
                {title:'paint pots',quantity:8,price:3.95},
                {title:'polka dots',quantity:17,price:12.95},
                {title:'pebbles',quantity:5,price:6.95}
            ];
            var totalcart = function() {
                var total = 0;
                for (var i=0,len=$scope.items.length;i<len;i++) {
                    total = total + $scope.items[i].price * $scope.items[i].quantity;
                }
                $scope.bill.totalcart = total;
                $scope.bill.discount = total > 100 ? 10 :0;
                $scope.bill.subtotal = total - $scope.bill.discount;
            }
            $scope.$watch('items',totalcart,true);//只用watch着items的变化
        }
    </script>
</head>
<body>
    <div ng-controller="cartcontroller">
        <div ng-repeat='item in items'>
            <span>{{item.title}}</span>
            <input ng-model='item.quantity'>
            <span>{{item.price | currency}}</span>
            <span>{{item.price * item.quantity | currency}}</span>
        </div>
        <div>total: {{bill.totalcart| currency }}</div>
        <div>discount: {{bill.discount | currency}}</div>
        <div>subtotal: {{bill.subtotal | currency}}</div>
    </div>
    <script type="text/javascript" src="angular.min.js"></script>
</body>
</html>

对于大型的itms数组来说,如果每次在angular显示页面时只重新计算bill属性,那么性能会好很多。通过创建一个带有watchfn的$watch函数,我们可以实现这一点。


$scope.$watch(
    var totalcart = function() {
                var total = 0;
                for (var i=0,len=$scope.items.length;i<len;i++) {
                    total = total + $scope.items[i].price * $scope.items[i].quantity;
                }
                $scope.bill.totalcart = total;
                $scope.bill.discount = total > 100 ? 10 :0;
                $scope.bill.subtotal = total - $scope.bill.discount;
            });

监控多个东西

如果你想监控多个属性或者对象,并且当其中任何一个发生变化时就会去执行一个函数,你有两种基本的选择:

监控把这些属性连接起来之后的值

把他们放在一个数组或者对象中,然后给deepwatch参数传递一个值

分别说明:
在第一种情况下,如果你的作用域中存在一个things对象,它带有两个属性a和b,当这两个属性发生变化时都需要执行callme()函数,你可以同时监控这两个属性 $scope.$watch('things.a + things.b',callme(...));
当列表非常长,你就需要写一个函数来返回连接之后的值。

在第二种情况下,需要监控things对象的所有属性,你可以这么做:


$scope.$watch('things',callme(...),true);

使用module组织依赖关系

provider(name,object or constructor()) 说明: 一个可配置的服务,创建逻辑比较的复杂。如果你传递了一个object作为参数,那么这个object对象必须带有一个名为$get的函数,这个函数需要返回服务的名称。否则,angularjs会认为你传递的时一个构造函数,调用构造函数会返回服务实例对象。
factory(name,$get function()) 说明:一个不可配置的服务,创建逻辑比较的复杂。你需要指定一个函数,当调用这个函数时,会返回服务实例。可以看成provider(name,{$get:$getfunction()})的形式。
service(name,constructor()) 一个不可配置的服务,创建逻辑比较的简单。与上面的provider函数的constructor参数类似,angular调用他可以创建服务实例。

使用module factory的例子


<html ng-app='shoppingmodule'>
<head>
<title>your shopping cart</title>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript">
    var shoppingmodule = angular.module('shoppingmodule',[]);
    shoppingmodule.factory('items',function() {
        var  items = {};
        items.query = function() {
            return [
                {title:'paint pots',description:'pots full of paint',price:3.95},
                {title:'paint pots',description:'pots full of paint',price:3.95},
                {title:'paint pots',description:'pots full of paint',price:3.95}
            ];
        };
        return items;
    });
    function shoppingcontroller($scope,items) {
        $scope.items = items.query();
    }
</script>
</head>
<body ng-controller='shoppingcontroller'>
<h1>shop!!</h1>
<table>
    <tr ng-repeat='item in items'>
        <td>{{item.title}}</td>
        <td>{{item.description}}</td>
        <td>{{item.price | currency}}</td>
    </tr>
</table>
</body>
</html>

引入第三方模块

在大多数应用中,创建供所有代码使用的单个模块,并把所有依赖的东西放入这个模块中,这样就会工作的很好。但是,如果你打算使用第三方包提供的服务或者指令,他们一般都带有自己的模块,你需要在应用模块中定义依赖关心才能引用他们。 例如:
var appmod = angular.module('app',['snazzy','super']);

关于filter的例子


<html ng-app='shoppingmodule'>
<head>
<title>your shopping cart</title>
<script type="text/javascript" src="angular.min.js"></script>
<script type="text/javascript">
    var shoppingmodule = angular.module('shoppingmodule',[]);
    shoppingmodule.filter('titlecase',function() {
        var titlecasefilter = function(input) {
            var words = input.split(' ');
            for(var i=0;i<words.length;i++) {
                words[i] = words[0].charat(0).touppercase() + words[i].slice(1);
            }
            return words.join(' ');
        };
        return titlecasefilter;
    });
    function shoppingcontroller($scope) {
        $scope.pageheading = 'this is a test case';
    }
</script>
</head>
<body ng-controller='shoppingcontroller'>
<h1>{{pageheading | titlecase}}</h1>
</body>
</html>

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网