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 相关文章推荐
用dom+xhtml+css制作的一个相册效果代码打包下载
Jan 24 Javascript
js跨域和ajax 跨域问题的实现思路
Sep 05 Javascript
js在数组中删除重复的元素自保留一个(两种实现思路)
Aug 22 Javascript
jQuery中map()方法用法实例
Jan 06 Javascript
基于jQuery实现网页进度显示插件
Mar 04 Javascript
JavaScript中的toUTCString()方法使用详解
Jun 12 Javascript
基于javascript实现仿百度输入框自动匹配功能
Jan 03 Javascript
基于jquery实现左右上下移动效果
May 02 jQuery
element上传组件循环引用及简单时间倒计时的实现
Oct 01 Javascript
JavaScript惰性载入函数实例分析
Mar 27 Javascript
vue3 watch和watchEffect的使用以及有哪些区别
Jan 26 Vue.js
分享一个vue实现的记事本功能案例
Apr 11 Vue.js
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
多重?l件?合查?(二)
2006/10/09 PHP
php编写的一个E-mail验证类
2015/03/25 PHP
微信公众号开发之文本消息自动回复php代码
2016/08/08 PHP
PHP5.6新增加的可变函数参数用法分析
2017/08/25 PHP
TP5框架model常见操作示例小结【增删改查、聚合、时间戳、软删除等】
2020/04/05 PHP
JS 创建对象(常见的几种方法)
2008/11/03 Javascript
真正的JQuery.ajax传递中文参数的解决方法
2011/05/28 Javascript
jQuery语法总结和注意事项小结
2012/11/11 Javascript
JS+JSP checkBox 全选具体实现
2014/01/02 Javascript
利用BootStrap弹出二级对话框的简单实现方法
2016/09/21 Javascript
vue2导航根据路由传值,而改变导航内容的实例
2017/11/10 Javascript
jquery动态添加带有样式的HTML标签元素方法
2018/02/24 jQuery
在layer弹层layer.prompt中,修改placeholder的实现方法
2019/09/27 Javascript
基于 Vue 的 Electron 项目搭建过程图文详解
2020/07/22 Javascript
Python实现国外赌场热门游戏Craps(双骰子)
2015/03/31 Python
Python命令行参数解析模块getopt使用实例
2015/04/13 Python
利用python写个下载teahour音频的小脚本
2017/05/08 Python
详解从Django Rest Framework响应中删除空字段
2019/01/11 Python
django model object序列化实例
2020/03/13 Python
python中time tzset()函数实例用法
2021/02/18 Python
使用Python webdriver图书馆抢座自动预约的正确方法
2021/03/04 Python
JD Sports瑞典:英国领先的运动时尚商店
2018/01/28 全球购物
广州御银科技股份有限公司试卷(C++)
2016/11/04 面试题
秋季运动会活动方案
2014/02/05 职场文书
餐饮总经理岗位职责
2014/03/07 职场文书
法学自荐信
2014/06/20 职场文书
二十年同学聚会致辞
2015/07/28 职场文书
2015年小学体育教师工作总结
2015/10/23 职场文书
一年级下册数学教学反思
2016/02/16 职场文书
《秋天的图画》教学反思
2016/02/19 职场文书
pytorch DataLoader的num_workers参数与设置大小详解
2021/05/28 Python
Pygame Rect区域位置的使用(图文)
2021/11/17 Python
苹果可能正在打击不进行更新的 App
2022/04/24 数码科技
Android基础入门之dataBinding的简单使用教程
2022/06/21 Java/Android
利用Java连接Hadoop进行编程
2022/06/28 Java/Android
Python使用plt.boxplot()函数绘制箱图、常用方法以及含义详解
2022/08/14 Python