1、Angular表達式 vs. Js 表達式javascript
這很容易讓人將angular視圖表達式聯想爲javascript表達式,但這並不徹底正確,由於angular不是經過javascript的eval()對錶達式進行求值。你能夠將angular表達式想象爲帶有如下差別的javascript表達式:css
屬性求值:全部屬性的求值是對於scope的,而javascript是對於window對象的。html
寬容(forgiving):表達式求值,對於undefined和null,angular是寬容的,但Javascript會產生NullPointerExceptions(-_-!!!!怎麼我沒見過)。java
沒有流程控制語句:在angular表達式裏,咱們不能作如下任何的事:條件分支、循環、拋出異常。express
過濾器(filters):咱們能夠就將表達式的結果傳入過濾器鏈(filter chains)。例如將日期對象轉換爲本地指定的人類可讀的格式。app
另外一方面,若是咱們想(在angular表達式中)執行任意的Javascript代碼,咱們能夠將那些代碼寫到Controller的一個方法中並調用它。若是咱們想在javascript中eval()一個angular表達式,能夠使用$eval()方法。函數
<!DOCTYPE HTML> <html ng-app="ExpressionTest"> <head> <meta charset="UTF-8"> <title>expression-e1</title> <style type="text/css"> .ng-cloak { display: none; } </style> </head> <body ng-controller="MyCtrl"> + 2 = {{1+2}} <br/> Expression: <input type="text" ng-model="expr"/> <button ng-click="addExp(expr)">Evaluate</button> <ul> <li ng-repeat="expr in exprs"> [<a ng-click="removeExp($index)" href="">X</a>] <tt>{{expr}}</tt>=><span ng-bind="$parent.$eval(expr)"></span> </li> </ul> <script src="../angular-1.0.1.js" type="text/javascript"></script> <script type="text/javascript"> var app = angular.module("ExpressionTest", []); app.controller("MyCtrl", function ($scope) { var exprs = $scope.exprs = []; $scope.expr = "3*10|currency"; $scope.addExp = function(expr) { exprs.push(expr); }; $scope.removeExp = function (index) { exprs.splice(index, 1); }; }); </script> </body> </html>
2、屬性求值(Property Evaluation)lua
angular的表達式解析環境的上下文是scope,而javascript則是window(應該是指嚴格模式evel的時候),angular須要經過$window訪問global window對象。例如,若是咱們須要在表達式中調用定義在window對象上的alert(),咱們須要使用$window.alert()。這樣作的用意是避免意外訪問了公共屬性(global state)(一個同源的小BUG?a common source of subtle bugs)spa
<!DOCTYPE HTML> <html ng-app="PropertyEvaluation"> <head> <meta charset="UTF-8"> <title>PropertyEvaluation</title> <style type="text/css"> .ng-cloak { display: none; } </style> </head> <body> <div ng-controller="MyCtrl"> Name: <input ng-model="name" type="text"/> <button ng-click="greet()">Greet</button> </div> <script src="../angular-1.0.1.js" type="text/javascript"></script> <script type="text/javascript"> var app = angular.module("PropertyEvaluation", []); app.controller("MyCtrl", function ($scope,$window) { $scope.name = "Kitty"; $scope.greet = function() { $window.alert("Hello " + $scope.name); }; }); </script> </body> </html>
3、Forgiving(寬容,容錯?)code
表達式求值對undefined和null是寬容的。在javascript中,當a不是object的時候,對a.b.c求值,那麼將會拋出一個異常。有時候這對於通用語言來講是合理的,而表達式求值主要用於數據綁定,通常形式以下:
{{a.b.c}}
|
若是a不存在,沒有任何顯示彷佛比拋出異常更加合理(除非咱們等待服務端響應,不一下子就會被定義)。若是表達式求值時不夠寬容,那麼咱們如此混亂地寫綁定代碼:
{{((a||{}).b||{}).c}}
//這……
|
類似地,引用一個函數a.b.c()時,若是它是undefined或者null,那麼簡單地返回undefined。
4、沒有控制流程語句(No Control Flow Statements)
咱們不能夠在表達式中寫流程控制語句。背後的緣由是,angular的核心體系是應用的邏輯應當在controller(的scope)裏面,而不是在view裏面。若是咱們須要在視圖表達式中加入條件分支、循環或者拋出異常的話,能夠委託javascript方法去代替(能夠調用scope中的方法)。
5、過濾器(Filters)
當咱們向用戶呈現數據時,咱們可能須要將數據從原始格式轉換爲友好(可讀性強)的格式。例如,咱們有一個數據對象須要在顯示給用戶以前根據地域進行格式化。咱們能夠將表達式傳遞給一連串的過濾器,如:
name | uppercase
|
這表達式求值器可簡單地傳遞name的值到uppercase過濾器中。
鏈式過濾器使用這種語法:
value | filter1 | filter2
|
咱們也能夠傳送用冒號分割的參數到filter中,例如,以兩位小數的格式顯示123:
123 | number:2
|
6、前綴」$」
咱們可能會感到奇怪,前綴」$」的意義是什麼?它是angular爲了使自己的API名稱可以區別於其餘的API而使用的一個簡單的前綴(防止衝突)。若是angular不使用$,那麼對a.length()求值將返回undefined。由於a和angular自己都沒有定義這個屬性。
考慮到angular未來的版本可能會選擇增長length這個方法,這將令這個表達式的行爲發生改變。更糟糕的是,咱們開發者可能會建立一個length屬性,那麼將與angular發生衝突。這個問題存在由於angular經過增長方法擴展了當前存在的對象。經過加入前綴」$」,angular保留了特定的namespace,因此angular的開發者與使用angular的開發者均可以和諧共處。