AngularJS语法详解(续)

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>

(0)

相关推荐

  • javascript基本语法

    1.运算符 运算符就是完成操作的一系列符号,它有七类: 赋值运算符(=,+=,-=,*=,/=,%=,<<=,>>=,|=,&=).算术运算符(+,-,*,/,++,--,%).比较运算符(>,<,<=,>=,==,===,!=,!==).逻辑运算符(||,&&,!).条件运算(?:).位移运算符(|,&,<<,>>,~,^)和字符串运算符(+). 可能很多人不知道"==="是什么.

  • js正则表达式基本语法(精粹)

    1.正则表达式基本语法 两个特殊的符号'^'和'$'.他们的作用是分别指出一个字符串的开始和结束. 例子如下: "^The":表示所有以"The"开始的字符串("There","The cat"等): "of despair$":表示所以以"of despair"结尾的字符串: "^abc$":表示开始和结尾都是"abc"的字符串--呵呵,只有&q

  • javascript基础语法——全面理解变量和标识符

    关于javascript,第一个比较重要的概念是变量,变量的工作机制是javascript的基本特性.实际上,变量是标识符的一种.本文将详细介绍变量和标识符 定义 标识符(Identifier)就是一个名字,用来对变量.函数.属性.参数进行命名,或者用做某些循环语句中的跳转位置的标记 //变量 var Identifier = 123; //属性 (new Object).Identifier = 'test'; //函数及参数 function IdentifierName(Identifie

  • JavaScript基础语法之js表达式

    本文将详细介绍javascript表达式,表达式分为原始表达式和复杂表达式.一般,关于javascript基础语法,人们听得比较多的术语是操作符和语句.但,其实还有一个术语经常使用,却很少被提到,这就是javascript表达式(expression). 原始表达式(primary exression) 原始表达式是表达式的最小单位--它不再包含其他表达式.javascript中的原始表达式包括this关键字.标识符引用.字面量引用.数组初始化.对象初始化和分组表达式 PrimaryExpres

  • javaScript语法总结

    一:语法 JavaScript:一种基于对象和事件驱动得客户端脚本语言: 由下面三者组成: 1,ECMAScript(一种由Ecma国际(前身为欧洲计算机制造商协会,European Computer Manufacturers Association,通过ECMA-262标准化的脚本程序设计语言); 2,Bom(browser object model的缩写,简称浏览器对象模型); 3,Dom(Document Object Model,文档对象模型,简称DOM),是W3C组织推荐的处理可扩展

  • AngularJS语法详解

    模板和数据的基本运作流程如下: 用户请求应用起始页面 用户的浏览器向服务器发起一次http连接,然后加载index.html页面,这个页面包含了模板 angular被加载到页面中,等待页面加载完成,查找ng-app指令,用来定义模板的边界 angular遍历模板,查找指定和绑定关系,将触发一些列动作:注册监听器.执行一些DOM操作.从服务器获取初始化数据.最后,应用将会启动起来,并将模板转换成DOM视图 连接到服务器去加载需要展示给用户的其他数据 显示文本 一种使用{{}}形式,如{{greet

  • Javascript中级语法快速入手

    1. 谈谈Javascript的对象 Javascript作为一种弱语言类型的语言,同时也是一种动态类型的语言.在使用Javascript的过程中,也常常需要用到Javascript的内置对象以及自定义的对象. 1.1 如何创建对象 Javascript是一种弱语言类型的语言,不必像Java.C#等高级语言那样必须通过构造函数的方法来创建对象,在Javascript中,主要有两种创建对象的方法,一种是直接通过new关键字定义,一种是通过函数来定义.如下: //第一种方式,直接通过new创建对象:

  • Javascript 6里的4个新语法

    JS 的 ES6版本已经被各大浏览器广泛支持,很多前端框架也已经使用 ES6,并且还有 Babel 可以做兼容处理,所以ES6已经进入了应用阶段 如果您对 ES6 还不太熟悉,下面4个简单的基础用法可以帮助您快速了解ES6 1.使用 let 和 const 声明变量 在传统的 ES5 代码中,变量的声明有两个主要问题 (1)缺少块儿作用域的支持 (2)不能声明常量 ES6中,这两个问题被解决了,增加了两个新的关键字:let 和 const 块儿作用域使用 let var a = 1; if (t

  • NodeJs基本语法和类型

    写在前面 今天想要查下Node的类型什么的知识,想要总结下,在Googol上看到一个文章,但是原始的链接不在了,在快照中把这篇文章拉出来,如果原作者有问题,请联系我! 该文章都是一些JS的基础,高手自动跳过!我之前没怎么写过js,这方面比较弱,所以在写node的时候也遇到了麻烦,这里给自己补充下知识! 正文 Node.js 的基础是 JavaScript 这门 脚本语言.而大多数的脚本语言一个共同的特点就是"弱类型". 不同于 PHP 的是,PHP 就是是有了新变量也无需申明,而 Ja

  • JavaScript正则表达式上之基本语法(推荐)

    相关阅读: js正则表达式基本语法(精粹) 正则表达式语法 一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式.该模式描述在查找文字主体时待匹配的一个或多个字符串.正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配. 定义 JavaScript种正则表达式有两种定义方式,定义一个匹配类似 <%XXX%> 的字符串 1. 构造函数 复制代码 代码如下: var reg=new RegExp('<%[^%>]+%>','g')

随机推荐