AngularJS语法详解(续)


Posted in Javascript onJanuary 23, 2015

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>
Javascript 相关文章推荐
JQuery 获得绝对,相对位置的坐标方法
Feb 09 Javascript
JavaScript中的变量作用域介绍
Dec 31 Javascript
原生JS实现LOADING效果
Mar 16 Javascript
轻量级的原生js日历插件calendar.js使用指南
Apr 28 Javascript
Highcharts学习之数据列
Aug 03 Javascript
JS前端开发判断是否是手机端并跳转操作(小结)
Feb 05 Javascript
easyui combogrid实现本地模糊搜索过滤多列
May 13 Javascript
JavaScript学习总结之正则的元字符和一些简单的应用
Jun 30 Javascript
Vue.js实例方法之生命周期详解
Jul 03 Javascript
Bootstrap datepicker日期选择器插件使用详解
Jul 26 Javascript
基于jquery实现左右上下移动效果
May 02 jQuery
LayUI动态设置checkbox不显示的解决方法
Sep 02 Javascript
Jquery动态替换div内容及动态展示的方法
Jan 23 #Javascript
AngularJS语法详解
Jan 23 #Javascript
JQuery选择器绑定事件及修改内容的方法
Jan 23 #Javascript
angular中使用路由和$location切换视图
Jan 23 #Javascript
JavaScript中的类与实例实现方法
Jan 23 #Javascript
PHP中CURL的几个经典应用实例
Jan 23 #Javascript
Javascript闭包用法实例分析
Jan 23 #Javascript
You might like
一个比较不错的PHP日历类分享
2014/11/18 PHP
php设置页面超时时间解决方法
2015/09/22 PHP
php示例详解Constructor Prototype Pattern 原型模式
2015/10/15 PHP
CI框架实现创建自定义类库的方法
2018/12/25 PHP
浅析document.ready和window.onload的区别讲解
2013/12/18 Javascript
NodeJS学习笔记之网络编程
2014/08/03 NodeJs
jQuery中nextAll()方法用法实例
2015/01/07 Javascript
jquery滚动特效集锦
2015/06/03 Javascript
浅谈javascript中关于日期和时间的基础知识
2016/07/13 Javascript
AngularJS 指令的交互详解及实例代码
2016/09/14 Javascript
Angularjs分页查询的实现
2017/02/24 Javascript
javascript数据结构中栈的应用之符号平衡问题
2017/04/11 Javascript
基于vue开发的在线付费课程应用过程
2018/01/25 Javascript
axios向后台传递数组作为参数的方法
2018/08/11 Javascript
vue2.x集成百度UEditor富文本编辑器的方法
2018/09/21 Javascript
JS相册图片抖动放大展示效果的示例代码
2021/01/29 Javascript
[00:10]DOTA2全国高校联赛 以DOTA2会友
2018/05/30 DOTA
浅谈Python 中整型对象的存储问题
2016/05/16 Python
SVM基本概念及Python实现代码
2017/12/27 Python
python matplotlib 在指定的两个点之间连线方法
2018/05/25 Python
对python中基于tcp协议的通信(数据传输)实例讲解
2019/07/22 Python
python 利用matplotlib在3D空间中绘制平面的案例
2021/02/06 Python
手机端用rem+scss做适配的详解
2017/11/15 HTML / CSS
如何配置、使用和清除Smarty缓存
2015/12/23 面试题
NET程序员上机面试题
2015/05/23 面试题
下面代码从性能上考虑,有什么问题
2015/04/03 面试题
校园创业策划书
2014/01/14 职场文书
自考生自我评价分享
2014/01/18 职场文书
计算机专业优秀大学生自我总结
2014/01/21 职场文书
2014年青年志愿者工作总结
2014/12/09 职场文书
党员个人党性分析材料
2014/12/18 职场文书
寻衅滋事罪辩护词
2015/05/21 职场文书
超市店长竞聘书
2015/09/15 职场文书
Python实战之疫苗研发情况可视化
2021/05/18 Python
用Python监控你的朋友都在浏览哪些网站?
2021/05/27 Python
python井字棋游戏实现人机对战
2022/04/28 Python