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 相关文章推荐
关于捕获用户何时点击window.onbeforeunload的取消事件
Mar 06 Javascript
23个超流行的jQuery相册插件整理分享
Apr 25 Javascript
浅谈javascript的原型继承
Jul 25 Javascript
JS+CSS实现简单的二级下拉导航菜单效果
Sep 21 Javascript
整理JavaScript创建对象的八种方法
Nov 03 Javascript
JavaScript给input的value赋值引发的关于基本类型值和引用类型值问题
Dec 07 Javascript
浅谈jQuery双事件多重加载的问题
Oct 05 Javascript
AngularJS打开页面隐藏显示表达式用法示例
Dec 25 Javascript
ES6使用let命令更简单的实现块级作用域实例分析
Mar 31 Javascript
node.js + socket.io 实现点对点随机匹配聊天
Jun 30 Javascript
基于Vue2x的图片预览插件的示例代码
May 14 Javascript
Vite + React从零开始搭建一个开源组件库
Jun 25 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
PHPMYADMIN 简明安装教程 推荐
2010/03/07 PHP
php中对2个数组相加的函数
2011/06/24 PHP
Codeigniter购物车类不能添加中文的解决方法
2014/11/29 PHP
基于PHPexecl类生成复杂的报表表头示例
2016/10/14 PHP
借助script进行Http跨域请求:JSONP实现原理及代码
2013/03/19 Javascript
我的Node.js学习之路(一)
2014/07/06 Javascript
jQuery 和 CSS 的文本特效插件集锦
2014/12/12 Javascript
深入理解JavaScript系列(18):面向对象编程之ECMAScript实现
2015/03/05 Javascript
JavaScript实现数组在指定位置插入若干元素的方法
2015/04/06 Javascript
jQuery中的AjaxSubmit使用讲解
2016/09/25 Javascript
微信小程序 登陆流程详细介绍
2017/01/17 Javascript
AngularJS表单提交实例详解
2017/02/18 Javascript
鼠标经过出现气泡框的简单实例
2017/03/17 Javascript
layui选项卡效果实现代码
2017/05/19 Javascript
Express + Node.js实现登录拦截器的实例代码
2017/07/01 Javascript
vue利用axios来完成数据的交互
2018/03/23 Javascript
详解jQuery设置内容和属性
2019/04/11 jQuery
node.js +mongdb实现登录功能
2020/06/18 Javascript
在Python程序中操作文件之flush()方法的使用教程
2015/05/24 Python
python监控进程脚本
2018/04/12 Python
Python简单实现两个任意字符串乘积的方法示例
2018/04/12 Python
Python(TensorFlow框架)实现手写数字识别系统的方法
2018/05/29 Python
解决pycharm下os.system执行命令返回有中文乱码的问题
2019/07/07 Python
Python实现Restful API的例子
2019/08/31 Python
python使用协程实现并发操作的方法详解
2019/12/27 Python
Python grpc超时机制代码示例
2020/09/14 Python
html+css实现自定义图片上传按钮功能
2019/09/04 HTML / CSS
英国书籍、CD、DVD和游戏的第一道德零售商:Awesome Books
2020/02/22 全球购物
通信工程毕业生求职信
2013/11/16 职场文书
房屋转让协议书
2014/04/11 职场文书
学校总务处领导干部个人对照检查材料思想汇报
2014/10/06 职场文书
工作失职检讨书
2015/01/26 职场文书
nginx的zabbix 5.0安装部署的方法步骤
2021/07/16 Servers
开发微信小程序之WXSS样式教程
2022/04/18 HTML / CSS
第四次工业革命,打工人与机器人的竞争
2022/04/21 数码科技
Python 中面向接口编程
2022/05/20 Python